<template>
  <div>
    <!--提交任务和搜索过滤-->
    <div style="margin-bottom: 10px; display: flex; justify-content: space-between; align-items: center">
      <div>
        <el-button type="primary" size="small" @click="add()">提交任务</el-button>
        <el-button-group>
          <el-button type="danger" size="small" @click="batchDelete()">批量删除</el-button>
          <el-button type="warning" size="small" @click="batchOperation('suspend')" :disabled="!multipleSelection.length">批量暂停</el-button>
          <el-button type="success" size="small" @click="batchOperation('started')" :disabled="!multipleSelection.length">批量启动</el-button>
        </el-button-group>
      </div>
      <div style="display: flex; align-items: center">
        <el-input
          placeholder="搜索任务ID或名称"
          v-model="searchQuery"
          size="small"
          style="width: 200px; margin-right: 10px"
          @input="handleSearch"
          clearable
        >
          <el-button slot="append" icon="el-icon-search"></el-button>
        </el-input>
        <el-select v-model="statusFilter" placeholder="状态过滤" size="small" @change="handleSearch" clearable>
          <el-option
            v-for="(value, key) in states"
            :key="key"
            :label="value"
            :value="key"
          ></el-option>
        </el-select>
      </div>
    </div>
    <!--表格数据-->
    <el-table
      ref="multipleTable"
      :data="dataShow"
      border
      class="table"
      width="100%"
      header-cell-class-name="table-header"
      @selection-change="handleSelectionChange"
      v-loading="tableLoading"
      element-loading-text="加载中..."
    >
      <el-table-column type="selection" width="55" />
      <el-table-column prop="taskId" label="任务ID" width="240" sortable />
      <el-table-column :show-overflow-tooltip="true" label="任务名" width="120">
        <template #default="scope">
          <span v-if="scope.row.taskName != undefined">{{
            scope.row.taskName
          }}</span>
          <span v-else>null</span>
        </template>
      </el-table-column>
      <el-table-column label="状态" width="100" prop="taskState">
        <template #default="scope">
          <el-tooltip :content="getStatusTooltip(scope.row)" placement="top">
            <div>
              <el-tag :type="taskState[scope.row.taskState].color" size="small">
                {{ taskState[scope.row.taskState].zh }}
              </el-tag>
              <el-progress 
                v-if="scope.row.taskState === 'started'" 
                :percentage="getTaskProgress(scope.row)" 
                :stroke-width="5" 
                :show-text="false"
                style="margin-top: 5px;"
              ></el-progress>
            </div>
          </el-tooltip>
        </template>
      </el-table-column>
      <el-table-column
        :show-overflow-tooltip="true"
        prop="pluginId"
        label="插件ID"
        width="250"
      />
      <el-table-column
        :show-overflow-tooltip="true"
        prop="mydataharborCreatorClazz"
        label="创建器"
      />
      <!--   <el-table-column prop="groupName" label="组名" width="100"></el-table-column>-->
      <el-table-column label="故障转移" width="120">
        <template #default="scope">
          <el-tag v-if="scope.row.enableRebalance" size="small">true</el-tag>
          <el-tag v-else size="small" type="warning">false</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="负载均衡" width="120">
        <template #default="scope">
          <el-tag v-if="scope.row.enableLoadBalance" size="small">true</el-tag>
          <el-tag v-else size="small" type="warning">false</el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="totalNumberOfPipeline" label="管道数" width="80" />
      <el-table-column label="创建时间" width="144" prop="createTime">
        <template slot-scope="scope">
          <span>{{
            scope.row.createTime | parseTime("{y}-{m}-{d} {h}:{i}")
          }}</span>
        </template>
      </el-table-column>
      <el-table-column label="更新时间" width="144" prop="lastUpdateTime">
        <template slot-scope="scope">
          <span>{{
            scope.row.lastUpdateTime | parseTime("{y}-{m}-{d} {h}:{i}")
          }}</span>
        </template>
      </el-table-column>
      <el-table-column :show-overflow-tooltip="true" label="tags" width="120">
        <template #default="scope">
          <span v-if="scope.row.tags != undefined">{{ scope.row.tags }}</span>
          <span v-else>null</span>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" fixed="right" width="120">
        <template #default="scope">
          <el-dropdown split-button type="primary" size="mini" @click="taskDetail(scope.row)" @command="handleCommand($event, scope.row)">
            详情
            <el-dropdown-menu slot="dropdown">
              <el-dropdown-item command="update">修改</el-dropdown-item>
              <el-dropdown-item command="recreate" divided>重建</el-dropdown-item>
              <el-dropdown-item command="fork">复制</el-dropdown-item>
              <el-dropdown-item command="state" divided>状态管理</el-dropdown-item>
              <el-dropdown-item v-if="scope.row.taskState !== 'started'" command="start">启动</el-dropdown-item>
              <el-dropdown-item v-if="scope.row.taskState === 'started'" command="suspend">暂停</el-dropdown-item>
              <el-dropdown-item command="delete" divided style="color: #F56C6C;">删除</el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>
        </template>
      </el-table-column>
    </el-table>
    <!--分页-->
    <div class="pagination">
      <el-pagination
        :current-page="currentPage"
        :page-sizes="[5, 10, 20, 50, 100]"
        :page-size="pageSize"
        :total="pageTotal"
        background
        layout="sizes, total, prev, pager, next"
        @size-change="handleSizeChange"
        @current-change="handlePageChange"
      />
    </div>
    <!--提交/fork任务弹框-->
    <el-dialog
      :title="dialogName"
      :visible.sync="dialogFormVisible"
      width="80%"
      @close="recreateClose"
      :close-on-click-modal="false"
    >
      <el-form :model="form" label-position="left" label-width="70px">
        <el-row>
          <el-col :span="8">
            <el-form-item label="组名">
              <el-input
                v-model="form.groupName"
                autocomplete="off"
                size="small"
                style="width: 80%"
                disabled
              />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="任务名">
              <el-input
                v-model="form.taskName"
                placeholder="请输入任务名"
                autocomplete="off"
                size="small"
                style="width: 80%"
              />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="管道数">
              <el-input
                v-model="form.totalNumberOfPipeline"
                autocomplete="off"
                size="small"
                style="width: 80%"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="插件ID" prop="pluginId">
              <el-select
                v-model="form.pluginId"
                placeholder="请选择组件ID"
                size="small"
                style="width: 90%"
                @change="selectPluginId"
              >
                <el-option
                  v-for="item in pluginInstallList"
                  :key="item.id"
                  :label="item.pluginId"
                  :value="item.pluginId"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="创建器">
              <el-select
                v-model="form.mydataharborCreatorClazz"
                placeholder="请选择CreatorClazz"
                size="small"
                style="width: 90%"
                @change="creatorClazzChange"
              >
                <el-option
                  v-for="item in clazzList"
                  :key="item.id"
                  :label="item.type + item.clazz"
                  :value="item.clazz"
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="故障转移">
              <el-select
                v-model="form.enableRebalance"
                placeholder="请选择是否设置故障转移"
                size="small"
                style="width: 90%"
              >
                <el-option label="true" value="true" />
                <el-option label="false" value="false" />
              </el-select>
            </el-form-item>
            <el-alert
              title="值为false，节点停机，任务将不会自动转移！但是会有告警信息发出，适合不能重复运行的任务"
              type="info"
              show-icon
              style="margin-top: -20px"
            />
          </el-col>
          <el-col :span="12">
            <el-form-item label="负载均衡">
              <el-select
                v-model="form.enableLoadBalance"
                placeholder="请选择是否设置负载均衡"
                size="small"
                style="width: 90%"
              >
                <el-option label="true" value="true" />
                <el-option label="false" value="false" />
              </el-select>
            </el-form-item>
            <el-alert
              title="当集群内有节点加入时，开启负载均衡的任务有可能会被重新分配到其他节点（任务会被有中断的过程），以便分散压力，如果不希望任务随意被停止转移请设置为false"
              type="info"
              show-icon
              style="margin-top: -20px"
            />
          </el-col>
        </el-row>
      </el-form>

      <el-collapse v-model="collapseActiveNames">
        <el-collapse-item title="settingContextConfig" name="settingConfig">
          <el-tabs v-model="defaultActiveModel">
            <el-tab-pane label="json" name="json">
              <vue-json-editor
                v-model="form.settingJsonConfig"
                :mode="'code'"
                lang="zh"
              />
            </el-tab-pane>

            <el-tab-pane label="参数说明" name="form">
              <el-tree
                :data="settingConfigJsonTreeData"
                :props="defaultProps"
                :default-expand-all="true"
                :render-content="renderTreeContent"
              />
            </el-tab-pane>
          </el-tabs>
        </el-collapse-item>
        <el-collapse-item title="taskConfig" name="taskConfig">
          <el-tabs v-model="taskConfigDefaultActiveModel">
            <el-tab-pane
              label="pipeline可视化配置"
              name="viewForm"
              v-if="
                form.mydataharborCreatorClazz ==
                  'mydataharbor.system.plugin.creator.CommonPipelineCreator'
              "
            >
              <el-steps :active="viewFormActiveIndex">
                <el-step
                  title="配置输入源"
                  description="选择并配置数据源和相应的协议转换器"
                ></el-step>
                <el-step
                  title="配置检查器"
                  description="可以配置多个检查器将不符合要求的协议数据过滤掉"
                ></el-step>
                <el-step
                  title="配置输出源"
                  description="选择要写入的目标数据源并配置参数"
                ></el-step>
                <el-step
                  title="配置数据转换器"
                  description="选择合适的数据转换器，这个步骤大部分是需要自己写代码的地方，当然也可以选择通用的数据转换器比如GroovyDataConverter"
                ></el-step>
              </el-steps>
              <div v-show="viewFormActiveIndex == 1" style="margin-top: 10px;">
                <el-form ref="form" label-width="100px">
                  <el-form-item label="选择输入源">
                    <el-select
                      v-model="selectedDataSourceName"
                      placeholder="请选择数据源"
                      style="width: 90%"
                      @change="dataSourceChange"
                    >
                      <el-option
                        v-for="dataSource in installDataSourceList"
                        :key="dataSource.name"
                        :label="dataSource.name"
                        :value="dataSource.name"
                      />
                    </el-select>
                    <el-tabs v-model="dataSourceActiveModel">
                      <el-tab-pane label="json" name="json">
                        <vue-json-editor
                          v-model="selectedDataSourceConfigJson"
                          :mode="'code'"
                          lang="zh"
                        />
                      </el-tab-pane>
                      <el-tab-pane label="组件参数说明" name="form">
                        <el-tree
                          :data="selectedDataSourceConfigJsonTreeData"
                          :props="defaultProps"
                          :default-expand-all="true"
                          :render-content="renderTreeContent"
                          empty-text="无需配置"
                        />
                      </el-tab-pane>
                      <el-tab-pane label="组件输出说明" name="tClassInfo">
                        <el-tree
                          :data="selectedDataSourceTclassInfoTreeData"
                          :props="defaultProps"
                          :default-expand-all="true"
                          :render-content="renderTreeContent"
                        />
                      </el-tab-pane>
                    </el-tabs>
                  </el-form-item>

                  <el-form-item label="协议转换器">
                    <el-select
                      v-model="selectedProtocolDataConverterName"
                      placeholder="请选择协议转换器"
                      style="width: 90%"
                      @change="protocolDataConverterChange"
                    >
                      <el-option
                        v-for="protocolDataConverter in installProtocolDataConverterList"
                        :key="protocolDataConverter.name"
                        :label="protocolDataConverter.name"
                        :value="protocolDataConverter.name"
                      >
                        <span style="float: left">{{
                          protocolDataConverter.name
                        }}</span>
                        <span
                          style="float: right; color: #8492a6; font-size: 13px"
                        >
                          <span
                            v-if="
                              selectedDataSource.tclassInfo != null &&
                                protocolDataConverter.tclassInfo.clazzStr ==
                                  selectedDataSource.tclassInfo.clazzStr
                            "
                          >
                            类型完全匹配√
                          </span>
                        </span>
                      </el-option>
                    </el-select>
                    <el-tabs v-model="protocolDataConverterActiveModel">
                      <el-tab-pane label="json" name="json">
                        <vue-json-editor
                          v-model="selectedProtocolDataConverterConfigJson"
                          :mode="'code'"
                          lang="zh"
                        />
                      </el-tab-pane>
                      <el-tab-pane label="组件参数说明" name="form">
                        <el-tree
                          :data="
                            selectedProtocolDataConverterConfigJsonTreeData
                          "
                          :props="defaultProps"
                          :default-expand-all="true"
                          :render-content="renderTreeContent"
                          empty-text="无需配置"
                        />
                      </el-tab-pane>

                      <el-tab-pane label="组件输入说明" name="tClassInfo">
                        <el-tree
                          :data="
                            selectedProtocolDataConverterTclassInfoTreeData
                          "
                          :props="defaultProps"
                          :default-expand-all="true"
                          :render-content="renderTreeContent"
                        />
                      </el-tab-pane>

                      <el-tab-pane label="组件输出说明" name="pClassInfo">
                        <el-tree
                          :data="
                            selectedProtocolDataConverterPclassInfoTreeData
                          "
                          :props="defaultProps"
                          :default-expand-all="true"
                          :render-content="renderTreeContent"
                        />
                      </el-tab-pane>
                    </el-tabs>
                  </el-form-item>
                </el-form>
              </div>
              <div v-show="viewFormActiveIndex == 2" style="margin-top: 10px;">
                <el-form ref="form" label-width="100px">
                  <el-form-item>
                    <el-button type="primary" plain @click="addChecker"
                      >添加</el-button
                    >
                  </el-form-item>

                  <el-form-item
                    :label="'过滤器' + (index + 1)"
                    v-for="(item, index) in selectedCheckerNames"
                    :key="index"
                  >
                    <el-select
                      v-model="selectedCheckerNames[index]"
                      placeholder="请选择过滤器"
                      style="width: 90%"
                      @change="checkerChange($event, index)"
                    >
                      <el-option
                        v-for="checker in installCheckers"
                        :key="checker.name"
                        :label="checker.name"
                        :value="checker.name"
                      >
                        <span style="float: left">{{ checker.name }}</span>
                        <span
                          style="float: right; color: #8492a6; font-size: 13px"
                        >
                          <span
                            v-if="
                              selectedProtocolDataConverter.pclassInfo !=
                                null &&
                                checker.pclassInfo.clazzStr ==
                                  selectedProtocolDataConverter.pclassInfo
                                    .clazzStr
                            "
                          >
                            类型完全匹配√
                          </span>
                        </span>
                      </el-option>
                    </el-select>
                    <el-button
                      type="danger"
                      icon="el-icon-delete"
                      circle
                      style="margin-left: 10px;"
                      @click="deleteChecker(index)"
                    ></el-button>
                    <el-tabs v-model="checkersActiveModel[index]">
                      <el-tab-pane label="json" name="json">
                        <vue-json-editor
                          v-model="selectedCheckerConfigJsons[index]"
                          :mode="'code'"
                          lang="zh"
                        />
                      </el-tab-pane>
                      <el-tab-pane label="组件参数说明" name="form">
                        <el-tree
                          :data="selectedCheckerConfigJsonTreeDatas[index]"
                          :props="defaultProps"
                          :default-expand-all="true"
                          :render-content="renderTreeContent"
                          empty-text="无需配置"
                        />
                      </el-tab-pane>

                      <el-tab-pane label="组件输入说明" name="tClassInfo">
                        <el-tree
                          :data="selectedCheckerPclassInfoTreeDatas[index]"
                          :props="defaultProps"
                          :default-expand-all="true"
                          :render-content="renderTreeContent"
                        />
                      </el-tab-pane>
                    </el-tabs>
                  </el-form-item>
                </el-form>
              </div>
              <div v-show="viewFormActiveIndex == 3" style="margin-top: 10px;">
                <el-form ref="form" label-width="100px">
                  <el-form-item label="输出源">
                    <el-select
                      v-model="selectedDataSinkName"
                      placeholder="请选择输出源"
                      style="width: 90%"
                      @change="dataSinkChange"
                    >
                      <el-option
                        v-for="dataSink in installDataSinkList"
                        :key="dataSink.name"
                        :label="dataSink.name"
                        :value="dataSink.name"
                      />
                    </el-select>
                    <el-tabs v-model="dataSinkActiveModel">
                      <el-tab-pane label="json" name="json">
                        <vue-json-editor
                          v-model="selectedDataSinkConfigJson"
                          :mode="'code'"
                          lang="zh"
                        />
                      </el-tab-pane>
                      <el-tab-pane label="组件参数说明" name="form">
                        <el-tree
                          :data="selectedDataSinkConfigJsonTreeData"
                          :props="defaultProps"
                          :default-expand-all="true"
                          :render-content="renderTreeContent"
                          empty-text="无需配置"
                        />
                      </el-tab-pane>
                      <el-tab-pane label="组件输入说明" name="pClassInfo">
                        <el-tree
                          :data="selectedDataSinkRclassInfoTreeData"
                          :props="defaultProps"
                          :default-expand-all="true"
                          :render-content="renderTreeContent"
                        />
                      </el-tab-pane>
                    </el-tabs>
                  </el-form-item>
                </el-form>
              </div>
              <div v-show="viewFormActiveIndex == 4" style="margin-top: 10px;">
                <el-form ref="form" label-width="100px">
                  <el-form-item label="数据转换器">
                    <el-select
                      v-model="selectedDataConverterName"
                      placeholder="请选择数据转换器"
                      style="width: 90%"
                      @change="dataConverterChange"
                    >
                      <el-option
                        v-for="dataConverter in installDataConverters"
                        :key="dataConverter.name"
                        :label="dataConverter.name"
                        :value="dataConverter.name"
                      >
                        <span style="float: left">{{
                          dataConverter.name
                        }}</span>
                        <span
                          style="float: right; color: #8492a6; font-size: 13px"
                        >
                          <span
                            v-if="
                              selectedProtocolDataConverter.pclassInfo !=
                                null &&
                                selectedDataSink.rclassInfo != null &&
                                dataConverter.pclassInfo.clazzStr ==
                                  selectedProtocolDataConverter.pclassInfo
                                    .clazzStr &&
                                dataConverter.rclassInfo.clazzStr ==
                                  selectedDataSink.rclassInfo.clazzStr
                            "
                          >
                            类型完全匹配
                          </span>
                        </span>
                      </el-option>
                    </el-select>
                    <el-tabs v-model="dataConverterActiveModel">
                      <el-tab-pane label="json" name="json">
                        <vue-json-editor
                          v-model="selectedDataConverterConfigJson"
                          :mode="'code'"
                          lang="zh"
                        />
                      </el-tab-pane>
                      <el-tab-pane label="组件参数说明" name="form">
                        <el-tree
                          :data="selectedDataConverterConfigJsonTreeData"
                          :props="defaultProps"
                          :default-expand-all="true"
                          :render-content="renderTreeContent"
                          empty-text="无需配置"
                        />
                      </el-tab-pane>

                      <el-tab-pane label="组件输入说明" name="pClassInfo">
                        <el-tree
                          :data="selectedDataConverterPclassInfoTreeData"
                          :props="defaultProps"
                          :default-expand-all="true"
                          :render-content="renderTreeContent"
                        />
                      </el-tab-pane>

                      <el-tab-pane label="组件输出说明" name="rClassInfo">
                        <el-tree
                          :data="selectedDataConverterRclassInfoTreeData"
                          :props="defaultProps"
                          :default-expand-all="true"
                          :render-content="renderTreeContent"
                        />
                      </el-tab-pane>
                    </el-tabs>
                  </el-form-item>
                </el-form>
              </div>
              <div style="text-align: center">
                <el-button
                  style="margin-top: 12px;"
                  @click="viewFormPre"
                  v-show="viewFormActiveIndex > 1"
                  >上一步</el-button
                >
                <el-button
                  style="margin-top: 12px;"
                  @click="viewFormNext"
                  v-show="viewFormActiveIndex < 4"
                  >下一步
                </el-button>
                <el-button
                  style="margin-top: 12px;"
                  @click="viewFormConfirm"
                  v-show="viewFormActiveIndex == 4"
                  type="primary"
                  plain
                  >生成json
                </el-button>
              </div>
            </el-tab-pane>

            <el-tab-pane label="json" name="json">
              <vue-json-editor
                v-model="form.configJson"
                :mode="'code'"
                lang="zh"
              />
            </el-tab-pane>

            <el-tab-pane label="参数说明" name="form">
              <el-tree
                :data="taskConfigJsonTreeData"
                :props="defaultProps"
                :default-expand-all="true"
                :render-content="renderTreeContent"
              />
            </el-tab-pane>
          </el-tabs>
        </el-collapse-item>
        <el-collapse-item title="tagConfig" name="tagConfig">
          <vue-json-editor v-model="form.tags" :mode="'code'" lang="zh" />
        </el-collapse-item>
      </el-collapse>

      <div slot="footer" class="dialog-footer">
        <el-button @click="cancel">取 消</el-button>
        <el-button type="primary" @click="submit">确 定</el-button>
      </div>
    </el-dialog>

    <!--任务详情-->
    <el-dialog :visible.sync="taskDetailVisible" title="任务详情" width="60%">
      <p>基本信息：</p>
      <el-table :data="taskDetailForm">
        <!--表格-->
        <el-table-column
          :show-overflow-tooltip="true"
          prop="taskId"
          label="任务ID"
        />
        <el-table-column
          :show-overflow-tooltip="true"
          prop="taskName"
          label="任务名称"
        />
        <el-table-column
          :show-overflow-tooltip="true"
          prop="pluginId"
          label="插件ID"
        />
        <el-table-column prop="mydataharborCreatorClazz" label="创建器" />
        <el-table-column prop="totalNumberOfPipeline" label="管道数" />
        <el-table-column label="故障转移">
          <template #default="scope">
            <el-tag v-if="scope.row.enableRebalance" size="small">true</el-tag>
            <el-tag v-else size="small" type="warning">false</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="负载均衡">
          <template #default="scope">
            <el-tag v-if="scope.row.enableLoadBalance" size="small"
              >true</el-tag
            >
            <el-tag v-else size="small" type="warning">false</el-tag>
          </template>
        </el-table-column>
      </el-table>
      <p>监控信息：</p>
      <el-table :data="taskMonitorInfos">
        <!--折叠-->
        <el-table-column
          :formatter="dateFormat"
          prop="lastRunTime"
          label="最近一次处理时间"
        />
        <el-table-column prop="recordCount" label="拉取总数" />
        <el-table-column prop="pollErrorCount" label="拉取异常次数" />
        <el-table-column
          prop="protocolConvertSuccessCount"
          label="协议转换成功数"
        />
        <el-table-column
          prop="protocolConvertErrorCount"
          label="协议转换失败数"
        />
        <el-table-column prop="checkerSuccessCount" label="校验通过数" />
        <el-table-column prop="checkerErrorCount" label="校验失败数" />
        <el-table-column
          prop="dataConvertSuccessCount"
          label="数据转换成功数"
        />
        <el-table-column prop="dataConvertErrorCount" label="数据转换失败数" />
        <el-table-column prop="writeSuccessCount" label="写入成功数" />
        <el-table-column prop="writeErrorCount" label="写入失败数" />
      </el-table>
      <p>任务分配信息：</p>
      <el-table :data="taskAssignedInfo">
        <!--折叠-->
        <el-table-column type="expand">
          <template slot-scope="props">
            <p>管道信息：</p>
            <p v-for="(value, key) in props.row.pipelineStates" :key="key">
              {{ key }}：{{ value }}
            </p>
            <el-divider />
            <p>写总计：</p>
            <p v-for="(value, key) in props.row.writeTotal" :key="key">
              {{ key }}：{{ value }}
            </p>
          </template>
        </el-table-column>
        <el-table-column prop="nodeName" label="节点" width="120" />
        <el-table-column prop="taskNum" label="任务数" width="80" />

        <el-table-column
          :show-overflow-tooltip="true"
          prop="createException"
          label="创建异常"
        >
          <template #default="scope">
            <span v-if="scope.row.createException == null">无</span>
            <span v-else>{{ scope.row.createException }}</span>
          </template>
        </el-table-column>
      </el-table>

      <p>任务设置</p>
      <vue-json-editor
        v-model="detailSettingJsonConfig"
        :mode="'code'"
        lang="zh"
      />
      <p>任务行为</p>
      <vue-json-editor v-model="detailConfigJson" :mode="'code'" lang="zh" />
      <p>tags其它属性</p>
      <vue-json-editor v-model="detailTags" :mode="'code'" lang="zh" />
      <div slot="footer" class="dialog-footer">
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>

    <!--任务修改弹框-->
    <el-dialog :visible.sync="dialogUpdateVisible" title="任务修改" width="60%">
      <el-form :model="updateForm" label-position="left">
        <el-row :gutter="20">
          <el-col :span="10">
            <el-form-item label="任务ID" label-width="70px">
              <el-input
                v-model="updateForm.taskId"
                autocomplete="off"
                disabled
              />
            </el-form-item>
          </el-col>
          <el-col :span="10">
            <el-form-item label="管道数" label-width="70px" prop="pluginId">
              <el-input
                v-model="updateForm.totalNumberOfPipeline"
                autocomplete="off"
              />
            </el-form-item>
          </el-col>
          <el-col :span="10">
            <el-form-item label="任务名" label-width="70px" prop="pluginId">
              <el-input
                v-model="updateForm.taskName"
                autocomplete="off"
              />
            </el-form-item>
          </el-col>
          <el-col :span="10">
            <el-form-item label="故障转移" label-width="70px" prop="version">
              <el-select
                v-model="updateForm.enableRebalance"
                placeholder="请选择是否故障转移"
              >
                <el-option label="true" value="true" />
                <el-option label="false" value="false" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="10">
            <el-form-item label="负载均衡" label-width="70px" prop="version">
              <el-select
                v-model="updateForm.enableLoadBalance"
                placeholder="请选择是否负载均衡"
              >
                <el-option label="true" value="true" />
                <el-option label="false" value="false" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="cancel">取 消</el-button>
        <el-button type="primary" @click="updateFormSubmit">确 定</el-button>
      </div>
    </el-dialog>

    <!--任务修改(重建)弹框-->
    <el-dialog
      :visible.sync="dialogRecreateUpdateVisible"
      title="重建任务（该操作会先销毁当前任务的所有管道实例，然后重新创建，很重的一种操作）"
      width="80%"
      @close="recreateClose"
    >
      <el-form :model="recreateUpdateForm" label-position="left">
        <el-row>
          <el-col :span="11">
            <el-form-item label="任务ID" label-width="70px">
              <el-input
                v-model="recreateUpdateForm.taskId"
                autocomplete="off"
                style="width: 250px;"
                disabled
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="8">
            <el-form-item label="组名">
              <el-input
                v-model="recreateUpdateForm.groupName"
                autocomplete="off"
                size="small"
                style="width: 80%"
                disabled
              />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="任务名">
              <el-input
                v-model="recreateUpdateForm.taskName"
                placeholder="请输入任务名"
                autocomplete="off"
                size="small"
                style="width: 80%"
              />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="管道数">
              <el-input
                v-model="recreateUpdateForm.totalNumberOfPipeline"
                autocomplete="off"
                size="small"
                style="width: 80%"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="插件ID" prop="pluginId">
              <el-select
                v-model="recreateUpdateForm.pluginId"
                placeholder="请选择组件ID"
                size="small"
                style="width: 90%"
                @change="selectPluginId"
              >
                <el-option
                  v-for="item in pluginInstallList"
                  :key="item.id"
                  :label="item.pluginId"
                  :value="item.pluginId"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="创建器">
              <el-select
                v-model="recreateUpdateForm.mydataharborCreatorClazz"
                placeholder="请选择CreatorClazz"
                size="small"
                style="width: 90%"
                @change="creatorClazzChange"
              >
                <el-option
                  v-for="item in clazzList"
                  :key="item.id"
                  :label="item.type + item.clazz"
                  :value="item.clazz"
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="故障转移">
              <el-select
                v-model="recreateUpdateForm.enableRebalance"
                placeholder="请选择是否设置故障转移"
                size="small"
                style="width: 90%"
              >
                <el-option label="true" value="true" />
                <el-option label="false" value="false" />
              </el-select>
            </el-form-item>
            <el-alert
              title="值为false，节点停机，任务将不会自动转移！但是会有告警信息发出，适合不能重复运行的任务"
              type="info"
              show-icon
              style="margin-top: -20px"
            />
          </el-col>
          <el-col :span="12">
            <el-form-item label="负载均衡">
              <el-select
                v-model="recreateUpdateForm.enableLoadBalance"
                placeholder="请选择是否设置负载均衡"
                size="small"
                style="width: 90%"
              >
                <el-option label="true" value="true" />
                <el-option label="false" value="false" />
              </el-select>
            </el-form-item>
            <el-alert
              title="当集群内有节点加入时，开启负载均衡的任务有可能会被重新分配到其他节点（任务会被有中断的过程），以便分散压力，如果不希望任务随意被停止转移请设置为false"
              type="info"
              show-icon
              style="margin-top: -20px"
            />
          </el-col>
        </el-row>
        <el-collapse v-model="collapseActiveNames">
          <el-collapse-item title="settingContextConfig" name="settingConfig">
            <el-tabs v-model="defaultActiveModel">
              <el-tab-pane label="json配置" name="json">
                <vue-json-editor
                  v-model="recreateUpdateForm.settingJsonConfig"
                  :mode="'code'"
                  lang="zh"
                />
              </el-tab-pane>

              <el-tab-pane label="参数说明" name="form">
                <el-tree
                  :data="settingConfigJsonTreeData"
                  :props="defaultProps"
                  :default-expand-all="true"
                  :render-content="renderTreeContent"
                />
              </el-tab-pane>
            </el-tabs>
          </el-collapse-item>
          <el-collapse-item title="taskConfig" name="taskConfig">
            <el-tabs v-model="taskConfigDefaultActiveModel">
              <el-tab-pane
                label="pipeline可视化配置"
                name="viewForm"
                v-if="
                  recreateUpdateForm.mydataharborCreatorClazz ==
                    'mydataharbor.system.plugin.creator.CommonPipelineCreator'
                "
              >
                <el-steps :active="viewFormActiveIndex">
                  <el-step
                    title="配置输入源"
                    description="选择并配置数据源和相应的协议转换器"
                  ></el-step>
                  <el-step
                    title="配置检查器"
                    description="可以配置多个检查器将不符合要求的协议数据过滤掉"
                  ></el-step>
                  <el-step
                    title="配置输出源"
                    description="选择要写入的目标数据源并配置参数"
                  ></el-step>
                  <el-step
                    title="配置数据转换器"
                    description="选择合适的数据转换器，这个步骤大部分是需要自己写代码的地方，当然也可以选择通用的数据转换器比如GroovyDataConverter"
                  ></el-step>
                </el-steps>
                <div
                  v-show="viewFormActiveIndex == 1"
                  style="margin-top: 10px;"
                >
                  <el-form ref="form" label-width="100px">
                    <el-form-item label="选择输入源">
                      <el-select
                        v-model="selectedDataSourceName"
                        placeholder="请选择数据源"
                        style="width: 90%"
                        @change="dataSourceChange"
                      >
                        <el-option
                          v-for="dataSource in installDataSourceList"
                          :key="dataSource.name"
                          :label="dataSource.name"
                          :value="dataSource.name"
                        />
                      </el-select>
                      <el-tabs v-model="dataSourceActiveModel">
                        <el-tab-pane label="json" name="json">
                          <vue-json-editor
                            v-model="selectedDataSourceConfigJson"
                            :mode="'code'"
                            lang="zh"
                          />
                        </el-tab-pane>
                        <el-tab-pane label="组件参数说明" name="form">
                          <el-tree
                            :data="selectedDataSourceConfigJsonTreeData"
                            :props="defaultProps"
                            :default-expand-all="true"
                            :render-content="renderTreeContent"
                            empty-text="无需配置"
                          />
                        </el-tab-pane>
                        <el-tab-pane label="组件输出说明" name="tClassInfo">
                          <el-tree
                            :data="selectedDataSourceTclassInfoTreeData"
                            :props="defaultProps"
                            :default-expand-all="true"
                            :render-content="renderTreeContent"
                          />
                        </el-tab-pane>
                      </el-tabs>
                    </el-form-item>

                    <el-form-item label="协议转换器">
                      <el-select
                        v-model="selectedProtocolDataConverterName"
                        placeholder="请选择协议转换器"
                        style="width: 90%"
                        @change="protocolDataConverterChange"
                      >
                        <el-option
                          v-for="protocolDataConverter in installProtocolDataConverterList"
                          :key="protocolDataConverter.name"
                          :label="protocolDataConverter.name"
                          :value="protocolDataConverter.name"
                        >
                          <span style="float: left">{{
                            protocolDataConverter.name
                          }}</span>
                          <span
                            style="float: right; color: #8492a6; font-size: 13px"
                          >
                            <span
                              v-if="
                                selectedDataSource.tclassInfo != null &&
                                  protocolDataConverter.tclassInfo.clazzStr ==
                                    selectedDataSource.tclassInfo.clazzStr
                              "
                            >
                              类型完全匹配√
                            </span>
                          </span>
                        </el-option>
                      </el-select>
                      <el-tabs v-model="protocolDataConverterActiveModel">
                        <el-tab-pane label="json" name="json">
                          <vue-json-editor
                            v-model="selectedProtocolDataConverterConfigJson"
                            :mode="'code'"
                            lang="zh"
                          />
                        </el-tab-pane>
                        <el-tab-pane label="组件参数说明" name="form">
                          <el-tree
                            :data="
                              selectedProtocolDataConverterConfigJsonTreeData
                            "
                            :props="defaultProps"
                            :default-expand-all="true"
                            :render-content="renderTreeContent"
                            empty-text="无需配置"
                          />
                        </el-tab-pane>

                        <el-tab-pane label="组件输入说明" name="tClassInfo">
                          <el-tree
                            :data="
                              selectedProtocolDataConverterTclassInfoTreeData
                            "
                            :props="defaultProps"
                            :default-expand-all="true"
                            :render-content="renderTreeContent"
                          />
                        </el-tab-pane>

                        <el-tab-pane label="组件输出说明" name="pClassInfo">
                          <el-tree
                            :data="
                              selectedProtocolDataConverterPclassInfoTreeData
                            "
                            :props="defaultProps"
                            :default-expand-all="true"
                            :render-content="renderTreeContent"
                          />
                        </el-tab-pane>
                      </el-tabs>
                    </el-form-item>
                  </el-form>
                </div>
                <div
                  v-show="viewFormActiveIndex == 2"
                  style="margin-top: 10px;"
                >
                  <el-form ref="form" label-width="100px">
                    <el-form-item>
                      <el-button type="primary" plain @click="addChecker"
                        >添加</el-button
                      >
                    </el-form-item>

                    <el-form-item
                      :label="'过滤器' + (index + 1)"
                      v-for="(item, index) in selectedCheckerNames"
                      :key="index"
                    >
                      <el-select
                        v-model="selectedCheckerNames[index]"
                        placeholder="请选择过滤器"
                        style="width: 90%"
                        @change="checkerChange($event, index)"
                      >
                        <el-option
                          v-for="checker in installCheckers"
                          :key="checker.name"
                          :label="checker.name"
                          :value="checker.name"
                        >
                          <span style="float: left">{{ checker.name }}</span>
                          <span
                            style="float: right; color: #8492a6; font-size: 13px"
                          >
                            <span
                              v-if="
                                selectedProtocolDataConverter.pclassInfo !=
                                  null &&
                                  checker.pclassInfo.clazzStr ==
                                    selectedProtocolDataConverter.pclassInfo
                                      .clazzStr
                              "
                            >
                              类型完全匹配√
                            </span>
                          </span>
                        </el-option>
                      </el-select>
                      <el-button
                        type="danger"
                        icon="el-icon-delete"
                        circle
                        style="margin-left: 10px;"
                        @click="deleteChecker(index)"
                      ></el-button>
                      <el-tabs v-model="checkersActiveModel[index]">
                        <el-tab-pane label="json" name="json">
                          <vue-json-editor
                            v-model="selectedCheckerConfigJsons[index]"
                            :mode="'code'"
                            lang="zh"
                          />
                        </el-tab-pane>
                        <el-tab-pane label="组件参数说明" name="form">
                          <el-tree
                            :data="selectedCheckerConfigJsonTreeDatas[index]"
                            :props="defaultProps"
                            :default-expand-all="true"
                            :render-content="renderTreeContent"
                            empty-text="无需配置"
                          />
                        </el-tab-pane>

                        <el-tab-pane label="组件输入说明" name="tClassInfo">
                          <el-tree
                            :data="selectedCheckerPclassInfoTreeDatas[index]"
                            :props="defaultProps"
                            :default-expand-all="true"
                            :render-content="renderTreeContent"
                          />
                        </el-tab-pane>
                      </el-tabs>
                    </el-form-item>
                  </el-form>
                </div>
                <div
                  v-show="viewFormActiveIndex == 3"
                  style="margin-top: 10px;"
                >
                  <el-form ref="form" label-width="100px">
                    <el-form-item label="输出源">
                      <el-select
                        v-model="selectedDataSinkName"
                        placeholder="请选择输出源"
                        style="width: 90%"
                        @change="dataSinkChange"
                      >
                        <el-option
                          v-for="dataSink in installDataSinkList"
                          :key="dataSink.name"
                          :label="dataSink.name"
                          :value="dataSink.name"
                        />
                      </el-select>
                      <el-tabs v-model="dataSinkActiveModel">
                        <el-tab-pane label="json" name="json">
                          <vue-json-editor
                            v-model="selectedDataSinkConfigJson"
                            :mode="'code'"
                            lang="zh"
                          />
                        </el-tab-pane>
                        <el-tab-pane label="组件参数说明" name="form">
                          <el-tree
                            :data="selectedDataSinkConfigJsonTreeData"
                            :props="defaultProps"
                            :default-expand-all="true"
                            :render-content="renderTreeContent"
                            empty-text="无需配置"
                          />
                        </el-tab-pane>
                        <el-tab-pane label="组件输入说明" name="pClassInfo">
                          <el-tree
                            :data="selectedDataSinkRclassInfoTreeData"
                            :props="defaultProps"
                            :default-expand-all="true"
                            :render-content="renderTreeContent"
                          />
                        </el-tab-pane>
                      </el-tabs>
                    </el-form-item>
                  </el-form>
                </div>
                <div
                  v-show="viewFormActiveIndex == 4"
                  style="margin-top: 10px;"
                >
                  <el-form ref="form" label-width="100px">
                    <el-form-item label="数据转换器">
                      <el-select
                        v-model="selectedDataConverterName"
                        placeholder="请选择数据转换器"
                        style="width: 90%"
                        @change="dataConverterChange"
                      >
                        <el-option
                          v-for="dataConverter in installDataConverters"
                          :key="dataConverter.name"
                          :label="dataConverter.name"
                          :value="dataConverter.name"
                        >
                          <span style="float: left">{{
                            dataConverter.name
                          }}</span>
                          <span
                            style="float: right; color: #8492a6; font-size: 13px"
                          >
                            <span
                              v-if="
                                selectedProtocolDataConverter.pclassInfo !=
                                  null &&
                                  selectedDataSink.rclassInfo != null &&
                                  dataConverter.pclassInfo.clazzStr ==
                                    selectedProtocolDataConverter.pclassInfo
                                      .clazzStr &&
                                  dataConverter.rclassInfo.clazzStr ==
                                    selectedDataSink.rclassInfo.clazzStr
                              "
                            >
                              类型完全匹配
                            </span>
                          </span>
                        </el-option>
                      </el-select>
                      <el-tabs v-model="dataConverterActiveModel">
                        <el-tab-pane label="json" name="json">
                          <vue-json-editor
                            v-model="selectedDataConverterConfigJson"
                            :mode="'code'"
                            lang="zh"
                          />
                        </el-tab-pane>
                        <el-tab-pane label="组件参数说明" name="form">
                          <el-tree
                            :data="selectedDataConverterConfigJsonTreeData"
                            :props="defaultProps"
                            :default-expand-all="true"
                            :render-content="renderTreeContent"
                            empty-text="无需配置"
                          />
                        </el-tab-pane>

                        <el-tab-pane label="组件输入说明" name="pClassInfo">
                          <el-tree
                            :data="selectedDataConverterPclassInfoTreeData"
                            :props="defaultProps"
                            :default-expand-all="true"
                            :render-content="renderTreeContent"
                          />
                        </el-tab-pane>

                        <el-tab-pane label="组件输出说明" name="rClassInfo">
                          <el-tree
                            :data="selectedDataConverterRclassInfoTreeData"
                            :props="defaultProps"
                            :default-expand-all="true"
                            :render-content="renderTreeContent"
                          />
                        </el-tab-pane>
                      </el-tabs>
                    </el-form-item>
                  </el-form>
                </div>
                <div style="text-align: center">
                  <el-button
                    style="margin-top: 12px;"
                    @click="viewFormPre"
                    v-show="viewFormActiveIndex > 1"
                    >上一步</el-button
                  >
                  <el-button
                    style="margin-top: 12px;"
                    @click="viewFormNext"
                    v-show="viewFormActiveIndex < 4"
                    >下一步
                  </el-button>
                  <el-button
                    style="margin-top: 12px;"
                    @click="viewFormConfirm"
                    v-show="viewFormActiveIndex == 4"
                    type="primary"
                    plain
                    >生成json
                  </el-button>
                </div>
              </el-tab-pane>

              <el-tab-pane label="json" name="json">
                <vue-json-editor
                  v-model="recreateUpdateForm.configJson"
                  :mode="'code'"
                  lang="zh"
                />
              </el-tab-pane>

              <el-tab-pane label="参数说明" name="form">
                <el-tree
                  :data="taskConfigJsonTreeData"
                  :props="defaultProps"
                  :default-expand-all="true"
                  :render-content="renderTreeContent"
                />
              </el-tab-pane>
            </el-tabs>
          </el-collapse-item>
          <el-collapse-item title="tagConfig" name="tagConfig">
            <vue-json-editor
              v-model="recreateUpdateForm.tags"
              :mode="'code'"
              lang="zh"
            />
          </el-collapse-item>
        </el-collapse>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="cancel">取 消</el-button>
        <el-button type="primary" @click="recreateUpdateFormSubmit"
          >确 定</el-button
        >
      </div>
    </el-dialog>

    <!--任务状态弹框-->
    <el-dialog :visible.sync="dialogStateVisible" title="任务状态" width="23%">
      <el-form :model="stateForm" label-position="left">
        <el-form-item label="任务ID" label-width="70px">
          <el-input
            v-model="stateForm.taskId"
            autocomplete="off"
            style="width: 250px;"
            disabled
          />
        </el-form-item>
        <el-form-item label="任务状态" label-width="70px" prop="version">
          <el-select
            v-model="stateForm.taskState"
            placeholder="请选择任务状态"
            style="width: 250px"
          >
            <el-option
              v-for="(key, value) in states"
              :key="key"
              :label="key"
              :value="value"
            />
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="cancel">取 消</el-button>
        <el-button type="primary" @click="updateStateFormSubmit"
          >确 定</el-button
        >
      </div>
    </el-dialog>
  </div>
</template>

<script>
import vueJsonEditor from "vue-json-editor";
import { parseTime } from "@/utils/index";

export default {
  inject: ["reload"],
  name: "Tasks",
  components: {
    vueJsonEditor
  },
  // 父组件传值
  props: ["groupName"],
  data() {
    return {
      // 当前组任务
      taskList: [],
      // 当前组插件
      pluginInstallList: [],
      // 插件的类路径
      clazzList: [],
      // 对话框
      dialogFormVisible: false,
      taskDetailVisible: false,
      dialogUpdateVisible: false,
      dialogRecreateUpdateVisible: false,
      dialogStateVisible: false,
      // 加载状态
      tableLoading: false,
      // 搜索和过滤
      searchQuery: '',
      statusFilter: '',
      filteredTaskList: [],
      // 提交任务数据
      form: {
        groupName: this.groupName,
        pluginId: "",
        taskName: "",
        mydataharborCreatorClazz: "",
        totalNumberOfPipeline: 1,
        enableRebalance: true,
        enableLoadBalance: true,
        settingJsonConfig: {},
        configJson: {},
        tags: {}
      },
      // 任务详情
      taskDetailForm: [],
      detailSettingJsonConfig: {},
      detailConfigJson: {},
      detailTags: {},
      taskAssignedInfo: [],

      // 状态
      taskState: {
        created: {
          zh: "创建",
          color: ""
        },
        started: {
          zh: "启动",
          color: "success"
        },
        suspend: {
          zh: "暂停",
          color: "info"
        },
        continued: {
          zh: "继续",
          color: "warning"
        },
        over: {
          zh: "结束",
          color: "over"
        }
      },
      states: {
        created: "创建",
        started: "启动",
        suspend: "暂停",
        continued: "继续",
        over: "结束"
      },
      // 对话框标题
      dialogName: "提交任务",
      // 修改数据
      updateForm: {
        enableRebalance: true,
        enableLoadBalance: true,
        taskId: "",
        taskName: "",
        totalNumberOfPipeline: 0,
        tags: "",
        groupName: "",
        pluginId: "",
        mydataharborCreatorClazz: "",
        configJson: "",
        settingJsonConfig: ""
      },
      recreateUpdateForm: {
        taskId: "",
        configJson: {},
        settingJsonConfig: {},
        tags: {},
        mydataharborCreatorClazz: "",
        groupName: "",
        taskName: "",
        totalNumberOfPipeline: "",
        pluginId: "",
        enableRebalance: "",
        enableLoadBalance: ""
      },
      // 修改状态
      stateForm: {
        taskId: "",
        taskState: ""
      },

      /* 前端模拟分页*/
      // 所有页面的数据
      totalPage: [],
      // 每页显示数量
      pageSize: 10,
      // 共几页
      pageTotal: 1,
      // 当前显示的数据
      dataShow: [],
      // 默认当前显示第一页
      currentPage: 0,

      // 多选内容
      multipleSelection: [],

      collapseActiveNames: ["settingConfig", "taskConfig", "tagConfig"],
      defaultActiveModel: "json",
      taskConfigDefaultActiveModel: "json",
      dataSourceActiveModel: "json",
      protocolDataConverterActiveModel: "json",
      checkersActiveModel: [
        "json",
        "json",
        "json",
        "json",
        "json",
        "json",
        "json",
        "json",
        "json",
        "json",
        "json",
        "json",
        "json",
        "json",
        "json",
        "json",
        "json",
        "json",
        "json",
        "json",
        "json",
        "json",
        "json",
        "json",
        "json",
        "json",
        "json",
        "json",
        "json",
        "json",
        "json",
        "json",
        "json",
        "json",
        "json"
      ],
      dataConverterActiveModel: "json",
      dataSinkActiveModel: "json",

      settingConfigJsonTreeData: [],

      taskConfigJsonTreeData: [],

      defaultProps: {
        children: "fieldInfos",
        label: "fieldName"
      },

      taskMonitorInfos: [], // 任务监控信息
      viewFormActiveIndex: 1, //可视化表单当前激活项

      installDataSourceList: [], //所有安装的数据源
      selectedDataSourceName: "", //当前选中的数据源
      selectedDataSource: {}, //当前选中的数据源对象
      selectedDataSourceConfigJson: [], //输入源json配置
      selectedDataSourceConfigJsonTreeData: [], //输入源json配置说明
      selectedDataSourceTclassInfoTreeData: [], //输出类型

      installProtocolDataConverterList: [], //所有安装的协议数据转换器
      selectedProtocolDataConverterName: "", //选中的协议转换器
      selectedProtocolDataConverter: {}, //选中的协议转换器对象
      selectedProtocolDataConverterConfigJson: [], //协议转换器json配置
      selectedProtocolDataConverterConfigJsonTreeData: [], //协议转换器json配置说明
      selectedProtocolDataConverterTclassInfoTreeData: [], //协议转换器 输入类型
      selectedProtocolDataConverterPclassInfoTreeData: [], //协议转换器 输出类型

      installCheckers: [], //所有安装的数据检查器
      selectedCheckerNames: [], //选中的校验器，数组
      selectedCheckers: [], //选中的校验器对象，数组
      selectedCheckerConfigJsons: [], //校验器json配置
      selectedCheckerConfigJsonTreeDatas: [], //校验器json配置说明
      selectedCheckerPclassInfoTreeDatas: [], //校验器 输入类型

      installDataConverters: [], //所有安装的数据转换器
      selectedDataConverterName: "", //选中的数据转换器
      selectedDataConverter: {}, //选中的数据转换器对象
      selectedDataConverterConfigJson: [], //数据转换器json配置
      selectedDataConverterConfigJsonTreeData: [], //数据转换器json配置说明
      selectedDataConverterPclassInfoTreeData: [], //数据转换器输入类型
      selectedDataConverterRclassInfoTreeData: [], //数据转换器输出类型

      installDataSinkList: [], //所有安装的输出源
      selectedDataSinkName: "", //选中的目标输出源
      selectedDataSink: {}, //选中的目标输出源
      selectedDataSinkConfigJson: [], //输出源json配置
      selectedDataSinkConfigJsonTreeData: [], //输出源json配置说明
      selectedDataSinkRclassInfoTreeData: [], //输出源输入类型
      type: ""
    };
  },
  watch: {},
  mounted() {
    this.initData();
    this.getTasksByGroupName();
  },
  methods: {
    add() {
      this.dialogFormVisible = true;
      this.type = "add";
    },
    
    initAllComponent() {
      this.initSelectedDataSource();
      this.initselectedProtocolDataConverter();
      this.initSelectedCheckers();
      this.initSelectedDataConverter();
      this.initSelectedDataSink();
    },
    initSelectedDataSource() {
      this.selectedDataSourceName = "";
      this.selectedDataSource = {};
      this.selectedDataSourceConfigJson = [];
      this.selectedDataSourceConfigJsonTreeData = [];
      this.selectedDataSourceTclassInfoTreeData = [];
    },
    initselectedProtocolDataConverter() {
      this.selectedProtocolDataConverterName = ""; //选中的协议转换器
      this.selectedProtocolDataConverter = {}; //选中的协议转换器对象
      this.selectedProtocolDataConverterConfigJson = []; //协议转换器json配置
      this.selectedProtocolDataConverterConfigJsonTreeData = []; //协议转换器json配置说明
      this.selectedProtocolDataConverterTclassInfoTreeData = []; //协议转换器 输入类型
      this.selectedProtocolDataConverterPclassInfoTreeData = []; //协议转换器 输出类型
    },
    initSelectedCheckers() {
      this.selectedCheckerNames = []; //选中的校验器，数组
      this.selectedCheckers = []; //选中的校验器对象，数组
      this.selectedCheckerConfigJsons = []; //校验器json配置
      this.selectedCheckerConfigJsonTreeDatas = []; //校验器json配置说明
      this.selectedCheckerPclassInfoTreeDatas = []; //校验器 输入类型
    },
    initSelectedDataConverter() {
      this.selectedDataConverterName = ""; //选中的数据转换器
      this.selectedDataConverter = {}; //选中的数据转换器对象
      this.selectedDataConverterConfigJson = []; //数据转换器json配置
      this.selectedDataConverterConfigJsonTreeData = []; //数据转换器json配置说明
      this.selectedDataConverterPclassInfoTreeData = []; //数据转换器输入类型
      this.selectedDataConverterRclassInfoTreeData = []; //数据转换器输出类型
    },
    initSelectedDataSink() {
      this.selectedDataSinkName = ""; //选中的目标输出源
      this.selectedDataSink = {}; //选中的目标输出源
      this.selectedDataSinkConfigJson = []; //输出源json配置
      this.selectedDataSinkConfigJsonTreeData = []; //输出源json配置说明
      this.selectedDataSinkRclassInfoTreeData = []; //输出源输入类型
    },
    //可视化数据转换器变更
    async dataConverterChange(val) {
      if (this.selectedProtocolDataConverterName == "") {
        this.$message("请先选择协议转换器");
        this.selectedDataConverterName = "";
        return;
      }
      if (this.selectedDataSinkName == "") {
        this.$message("请先选择输出源");
        this.selectedDataConverterName = "";
        return;
      }
      for (var dataConverter of this.installDataConverters) {
        if (dataConverter.name == val) {
          this.selectedDataConverter = dataConverter;
        }
      }
      if (this.selectedDataConverter != null) {
        if (
          this.selectedDataConverter.pclassInfo.clazzStr !=
          this.selectedProtocolDataConverter.pclassInfo.clazzStr
        ) {
          await this.$message({
            message:
              "选中的数据转换器输入的数据类型和当前选中的协议转换器输出的数据类型不一致，请确保" +
              this.selectedProtocolDataConverter.pclassInfo.clazzStr +
              "是" +
              this.selectedDataConverter.pclassInfo.clazzStr +
              "的子类，否则任务将无法执行!",
            type: "warning",
            duration: 10000,
            showClose: true
          });
        }
        if (
          this.selectedDataConverter.rclassInfo.clazzStr !=
          this.selectedDataSink.rclassInfo.clazzStr
        ) {
          await this.$message({
            message:
              "选中的数据转换器输出的数据类型和当前选中的输出源输入的数据类型不一致，请确保" +
              this.selectedDataConverter.rclassInfo.clazzStr +
              "是" +
              this.selectedDataSink.rclassInfo.clazzStr +
              "的子类，否则任务将无法执行!",
            type: "warning",
            duration: 10000,
            showClose: true
          });
        }
        this.selectedDataConverterConfigJsonTreeData = this.selectedDataConverter.argsTypeInfo;
        this.selectedDataConverterTclassInfoTreeData = [
          this.selectedDataConverter.tclassInfo
        ];
        this.selectedDataConverterPclassInfoTreeData = [
          this.selectedDataConverter.pclassInfo
        ];
        if (this.selectedDataConverter.argsTypeInfo != null)
          this.selectedDataConverterConfigJson = this.buildArgsTypeInfo(
            this.selectedDataConverter.argsTypeInfo
          );
        else this.selectedDataConverterConfigJson = [];
      }

      console.log(this.selectedDataConverter);
    },
    //输出源变更
    dataSinkChange(val) {
      //寻找选中的数据源
      for (var dataSink of this.installDataSinkList) {
        if (dataSink.name == val) {
          this.selectedDataSink = dataSink;
        }
      }
      if (this.selectedDataSink != null) {
        this.selectedDataSinkConfigJsonTreeData = this.selectedDataSink.argsTypeInfo;
        this.selectedDataSinkRclassInfoTreeData = [
          this.selectedDataSink.rclassInfo
        ];
        if (this.selectedDataSink.argsTypeInfo != null) {
          this.selectedDataSinkConfigJson = this.buildArgsTypeInfo(
            this.selectedDataSink.argsTypeInfo
          );
        } else {
          this.selectedDataSinkConfigJson = [];
        }
        this.initSelectedDataConverter();
      }
      console.log(this.selectedDataSink);
    },
    //校验器变化
    checkerChange(val, index) {
      if (this.selectedProtocolDataConverterName == "") {
        this.$message("请先选择协议转换器");
        this.selectedCheckerNames[index] = "";
        return;
      }
      //寻找选中的校验器
      for (var checker of this.installCheckers) {
        if (checker.name == val) {
          this.selectedCheckers[index] = checker;
        }
      }
      if (this.selectedCheckers[index] != null) {
        if (
          this.selectedCheckers[index].pclassInfo.clazzStr !=
          this.selectedProtocolDataConverter.pclassInfo.clazzStr
        ) {
          this.$message({
            message:
              "选中的校验器器输入的数据类型和当前选中的协议转换器输出的数据类型不一致，请确保" +
              this.selectedProtocolDataConverter.pclassInfo.clazzStr +
              "是" +
              this.selectedCheckers[index].pclassInfo.clazzStr +
              "的子类，否则任务将无法执行!",
            type: "warning",
            duration: 10000,
            showClose: true
          });
        }
        this.selectedCheckerConfigJsonTreeDatas[index] = this.selectedCheckers[
          index
        ].argsTypeInfo;
        this.selectedCheckerPclassInfoTreeDatas[index] = [
          this.selectedCheckers[index].pclassInfo
        ];
        if (this.selectedCheckers[index].argsTypeInfo != null)
          this.selectedCheckerConfigJsons[index] = this.buildArgsTypeInfo(
            this.selectedCheckers[index].argsTypeInfo
          );
        else this.selectedCheckerConfigJsons[index] = [];
      }
      console.log(this.selectedCheckers[index]);
    },

    //删除校验器
    deleteChecker(index) {
      this.selectedCheckerNames.splice(index, 1);
      this.selectedCheckers.splice(index, 1);
      this.selectedCheckerConfigJsons.splice(index, 1);
      this.selectedCheckerConfigJsonTreeDatas.splice(index, 1);
      this.selectedCheckerPclassInfoTreeDatas.splice(index, 1);
    },
    //添加校验器
    addChecker() {
      this.selectedCheckerNames.push("");
      this.selectedCheckers.push({});
      this.selectedCheckerConfigJsons.push([]),
        this.selectedCheckerConfigJsonTreeDatas.push([]),
        this.selectedCheckerPclassInfoTreeDatas.push([]);
    },

    //可视化创建数据源变更
    dataSourceChange(val) {
      //寻找选中的数据源
      for (var dataSource of this.installDataSourceList) {
        if (dataSource.name == val) {
          this.selectedDataSource = dataSource;
        }
      }
      if (this.selectedDataSource != null) {
        this.selectedDataSourceConfigJsonTreeData = this.selectedDataSource.argsTypeInfo;
        this.selectedDataSourceTclassInfoTreeData = [
          this.selectedDataSource.tclassInfo
        ];
        if (this.selectedDataSource.argsTypeInfo != null)
          this.selectedDataSourceConfigJson = this.buildArgsTypeInfo(
            this.selectedDataSource.argsTypeInfo
          );
        else this.selectedDataSourceConfigJson = [];
        this.initselectedProtocolDataConverter();
      }
      console.log(this.selectedDataSource);
    },
    //可视化协议转换器变更
    protocolDataConverterChange(val) {
      if (this.selectedDataSourceName == "") {
        this.$message("请先选择输入源");
        this.selectedProtocolDataConverterName = "";
        return;
      }
      for (var protocolDataConverter of this.installProtocolDataConverterList) {
        if (protocolDataConverter.name == val) {
          this.selectedProtocolDataConverter = protocolDataConverter;
        }
      }
      if (this.selectedProtocolDataConverter != null) {
        if (
          this.selectedProtocolDataConverter.tclassInfo.clazzStr !=
          this.selectedDataSource.tclassInfo.clazzStr
        ) {
          this.$message({
            message:
              "协议转换器接受的数据类型和当前选中的输入源输入的数据类型不一致，请确保" +
              this.selectedDataSource.tclassInfo.clazzStr +
              "是" +
              this.selectedProtocolDataConverter.tclassInfo.clazzStr +
              "的子类，否则任务将无法执行!",
            type: "warning",
            duration: 10000,
            showClose: true
          });
        }
        this.selectedProtocolDataConverterConfigJsonTreeData = this.selectedProtocolDataConverter.argsTypeInfo;
        this.selectedProtocolDataConverterTclassInfoTreeData = [
          this.selectedProtocolDataConverter.tclassInfo
        ];
        this.selectedProtocolDataConverterPclassInfoTreeData = [
          this.selectedProtocolDataConverter.pclassInfo
        ];
        if (this.selectedProtocolDataConverter.argsTypeInfo != null)
          this.selectedProtocolDataConverterConfigJson = this.buildArgsTypeInfo(
            this.selectedProtocolDataConverter.argsTypeInfo
          );
        else this.selectedProtocolDataConverterConfigJson = [];
        this.initSelectedCheckers();
        this.initSelectedDataConverter();
      }

      console.log(this.selectedProtocolDataConverter);
    },
    dateFormat(row, column) {
      if (row.lastRunTime != 0) {
        const date = new Date(row.lastRunTime);
        const year = date.getFullYear();
        const month =
          date.getMonth() + 1 < 10
            ? `0${date.getMonth() + 1}`
            : date.getMonth() + 1;
        const day = date.getDate() < 10 ? `0${date.getDate()}` : date.getDate();
        const hour =
          date.getHours() < 10 ? `0${date.getHours()}` : date.getHours();
        const minute =
          date.getMinutes() < 10 ? `0${date.getMinutes()}` : date.getMinutes();
        const second =
          date.getSeconds() < 10 ? `0${date.getSeconds()}` : date.getSeconds();
        return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
      }
      return "暂无";
    },
    compare(property) {
      return function(a, b) {
        var value1 = a[property];
        var value2 = b[property];
        return value2 - value1;
      };
    },
    // 清空
    clearData() {
      this.form = {
        groupName: this.groupName,
        pluginId: "",
        mydataharborCreatorClazz: "",
        totalNumberOfPipeline: 1,
        enableRebalance: true,
        enableLoadBalance: true,
        settingJsonConfig: {},
        configJson: {}
      };
      this.taskDetailForm = [];
      this.dialogName = "提交任务";
    },
    initData() {
      // 获取当前组的任务名称
      this.taskList = [];
      this.multipleSelection = [];
      this.tableLoading = true;

      // 获取任务
      this.postRequest(
        "mydataharbor/task/listTaskByGroup?groupName=" + this.groupName
      ).then(res => {
        if (res.code == 0) {
          const allTask = res.data;
          for (const key in allTask) {
            const task = allTask[key];
            
            // 获取任务监控信息
            this.getRequest("mydataharbor/task/getTaskMonitorInfo", {
              taskId: task.taskId
            }).then(monitorRes => {
              if (monitorRes.code == 0) {
                task.taskMonitorInfo = monitorRes.data;
              }
            });
            
            this.taskList.push(task);
          }
          this.taskList.sort(this.compare("createTime"));
          
          // 应用搜索和过滤
          this.filteredTaskList = [...this.taskList];
          if (this.searchQuery || this.statusFilter) {
            this.handleSearch();
          } else {
            // 分页
            this.initPageData();
          }
        } else {
          this.$message.error(res.msg);
        }
        this.tableLoading = false;
      }).catch(() => {
        this.tableLoading = false;
        this.$message.error("获取任务列表失败");
      });
    },
    // 根据组名查询任务
    getTasksByGroupName() {
      this.tableLoading = true;
      this.getRequest(
        "/mydataharbor/node/plugin?groupName=" + this.groupName
      ).then(res => {
        this.pluginInstallList = res.data;
        this.initInstallComponentList();
        this.tableLoading = false;
      }).catch(() => {
        this.tableLoading = false;
        this.$message.error("获取插件列表失败");
      });
    },
    
    // 搜索和过滤任务
    handleSearch() {
      if (!this.searchQuery && !this.statusFilter) {
        this.filteredTaskList = [...this.taskList];
      } else {
        this.filteredTaskList = this.taskList.filter(task => {
          const matchesSearch = !this.searchQuery || 
            task.taskId.toLowerCase().includes(this.searchQuery.toLowerCase()) || 
            (task.taskName && task.taskName.toLowerCase().includes(this.searchQuery.toLowerCase()));
          
          const matchesStatus = !this.statusFilter || task.taskState === this.statusFilter;
          
          return matchesSearch && matchesStatus;
        });
      }
      
      // 重新初始化分页
      this.pageTotal = this.filteredTaskList.length;
      this.totalPage = {};
      
      for (let i = 0; i < Math.ceil(this.pageTotal / this.pageSize); i++) {
        this.totalPage[i + 1] = this.filteredTaskList.slice(
          this.pageSize * i,
          this.pageSize * (i + 1)
        );
      }
      
      this.handlePageChange(1);
    },
    
    // 获取任务状态提示
    getStatusTooltip(task) {
      const state = this.states[task.taskState];
      let tooltip = `状态: ${state}`;
      
      if (task.taskState === 'started') {
        tooltip += `\n处理总数: ${this.getTaskTotalCount(task)}`;
      }
      
      return tooltip;
    },
    
    // 获取任务进度
    getTaskProgress(task) {
      if (!task || !task.taskMonitorInfo) {
        return 0;
      }
      
      const total = this.getTaskTotalCount(task);
      if (total === 0) {
        return 0;
      }
      
      const processed = task.taskMonitorInfo ? task.taskMonitorInfo.writeSuccessCount || 0 : 0;
      return Math.min(Math.round((processed / total) * 100), 100);
    },
    
    // 获取任务总数
    getTaskTotalCount(task) {
      if (!task || !task.taskMonitorInfo) {
        return 0;
      }
      
      return task.taskMonitorInfo ? task.taskMonitorInfo.recordCount || 0 : 0;
    },
    
    // 批量操作任务状态
    batchOperation(state) {
      if (this.multipleSelection.length === 0) {
        this.$message.info("请先选择需要操作的任务！");
        return;
      }
      
      this.$confirm(`确定要将选中的${this.multipleSelection.length}个任务状态修改为${this.states[state]}吗？`, "确认信息", {
        distinguishCancelAndClose: true,
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        const promises = this.multipleSelection.map(task => {
          return this.postRequest(
            `mydataharbor/task/manageTaskState?taskId=${task.taskId}&taskState=${state}`
          );
        });
        
        Promise.all(promises).then(results => {
          const successCount = results.filter(res => res.code === 0).length;
          if (successCount > 0) {
            this.$message.success(`成功修改${successCount}个任务的状态`);
            this.initData();
          }
          
          const failCount = results.length - successCount;
          if (failCount > 0) {
            this.$message.warning(`${failCount}个任务状态修改失败`);
          }
        });
      });
    },

    //初始化所有安装组件的信息
    initInstallComponentList() {
      for (const key in this.pluginInstallList) {
        var pluginInfo = this.pluginInstallList[key];
        for (const key2 in pluginInfo.dataPipelineCreatorInfos) {
          var dataPipelineCreatorInfo =
            pluginInfo.dataPipelineCreatorInfos[key2];
          if (dataPipelineCreatorInfo.dataSourceClassInfo != null) {
            //数据源
            for (const key3 in dataPipelineCreatorInfo.dataSourceClassInfo) {
              var dataSource =
                dataPipelineCreatorInfo.dataSourceClassInfo[key3];
              for (const key4 in dataSource.constructorAndArgsConfigs) {
                var constructor = dataSource.constructorAndArgsConfigs[key4];
                var name =
                  pluginInfo.pluginId +
                  "[" +
                  dataSource.clazz +
                  "(" +
                  dataSource.title +
                  ")]" +
                  "constructor-" +
                  key4;
                var contain = false;
                for (var obj of this.installDataSourceList) {
                  if (obj.name == name) contain = true;
                }
                if (!contain)
                  this.installDataSourceList.push({
                    name: name,
                    pluginId: pluginInfo.pluginId,
                    clazz: dataSource.clazz,
                    argsType: constructor.argsType,
                    argsTypeInfo: constructor.argsTypeInfo,
                    tclassInfo: dataSource.tclassInfo
                  });
              }
            }
          }
          if (dataPipelineCreatorInfo.protocolConverterClassInfo != null) {
            //协议转换器
            for (const key3 in dataPipelineCreatorInfo.protocolConverterClassInfo) {
              var protocolConvertor =
                dataPipelineCreatorInfo.protocolConverterClassInfo[key3];
              for (const key4 in protocolConvertor.constructorAndArgsConfigs) {
                var constructor =
                  protocolConvertor.constructorAndArgsConfigs[key4];
                var name =
                  pluginInfo.pluginId +
                  "[" +
                  protocolConvertor.clazz +
                  "(" +
                  protocolConvertor.title +
                  ")]" +
                  "constructor-" +
                  key4;
                var contain = false;
                for (var obj of this.installProtocolDataConverterList) {
                  if (obj.name == name) contain = true;
                }
                if (!contain)
                  this.installProtocolDataConverterList.push({
                    name: name,
                    pluginId: pluginInfo.pluginId,
                    clazz: protocolConvertor.clazz,
                    argsType: constructor.argsType,
                    argsTypeInfo: constructor.argsTypeInfo,
                    tclassInfo: protocolConvertor.tclassInfo,
                    pclassInfo: protocolConvertor.pclassInfo
                  });
              }
            }
          }

          if (dataPipelineCreatorInfo.checkerClassInfo != null) {
            //过滤器
            for (const key3 in dataPipelineCreatorInfo.checkerClassInfo) {
              var checker = dataPipelineCreatorInfo.checkerClassInfo[key3];
              for (const key4 in checker.constructorAndArgsConfigs) {
                var constructor = checker.constructorAndArgsConfigs[key4];
                var name =
                  pluginInfo.pluginId +
                  "[" +
                  checker.clazz +
                  "(" +
                  checker.title +
                  ")]" +
                  "constructor-" +
                  key4;
                var contain = false;
                for (var obj of this.installCheckers) {
                  if (obj.name == name) contain = true;
                }
                if (!contain)
                  this.installCheckers.push({
                    name: name,
                    pluginId: pluginInfo.pluginId,
                    clazz: checker.clazz,
                    argsType: constructor.argsType,
                    argsTypeInfo: constructor.argsTypeInfo,
                    pclassInfo: checker.pclassInfo
                  });
              }
            }
          }

          if (dataPipelineCreatorInfo.dataConverterClassInfo != null) {
            //数据转换器
            for (const key3 in dataPipelineCreatorInfo.dataConverterClassInfo) {
              var dataConverter =
                dataPipelineCreatorInfo.dataConverterClassInfo[key3];
              for (const key4 in dataConverter.constructorAndArgsConfigs) {
                var constructor = dataConverter.constructorAndArgsConfigs[key4];
                var name =
                  pluginInfo.pluginId +
                  "[" +
                  dataConverter.clazz +
                  "(" +
                  dataConverter.title +
                  ")]" +
                  "constructor-" +
                  key4;
                var contain = false;
                for (var obj of this.installDataConverters) {
                  if (obj.name == name) contain = true;
                }
                if (!contain)
                  this.installDataConverters.push({
                    name: name,
                    pluginId: pluginInfo.pluginId,
                    clazz: dataConverter.clazz,
                    argsType: constructor.argsType,
                    argsTypeInfo: constructor.argsTypeInfo,
                    pclassInfo: dataConverter.pclassInfo,
                    rclassInfo: dataConverter.rclassInfo
                  });
              }
            }
          }

          if (dataPipelineCreatorInfo.dataSinkClassInfo != null) {
            //写入器
            for (const key3 in dataPipelineCreatorInfo.dataSinkClassInfo) {
              var dataSink = dataPipelineCreatorInfo.dataSinkClassInfo[key3];
              for (const key4 in dataSink.constructorAndArgsConfigs) {
                var constructor = dataSink.constructorAndArgsConfigs[key4];
                var name =
                  pluginInfo.pluginId +
                  "[" +
                  dataSink.clazz +
                  "(" +
                  dataSink.title +
                  ")]" +
                  "constructor-" +
                  key4;
                var contain = false;
                for (var obj of this.installDataSinkList) {
                  if (obj.name == name) contain = true;
                }
                if (!contain)
                  this.installDataSinkList.push({
                    name: name,
                    pluginId: pluginInfo.pluginId,
                    clazz: dataSink.clazz,
                    argsType: constructor.argsType,
                    argsTypeInfo: constructor.argsTypeInfo,
                    rclassInfo: dataSink.rclassInfo
                  });
              }
            }
          }
        }
      }
      console.log(this.installDataSourceList);
      console.log(this.installProtocolDataConverterList);
      console.log(this.installCheckers);
      console.log(this.installDataConverters);
      console.log(this.installDataSinkList);
    },

    // 提交任务
    submit() {
      // 表单验证
      if (!this.validateTaskForm()) {
        return;
      }
      
      this.$confirm("确认提交任务?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "info"
      }).then(() => {
        this.dialogFormVisible = false;
        this.tableLoading = true;
        
        // 深拷贝配置对象，避免修改原始对象
        const configJsonCopy = JSON.parse(JSON.stringify(this.form.configJson));
        const settingJsonConfigCopy = JSON.parse(JSON.stringify(this.form.settingJsonConfig));
        
        // 确保数据格式正确
        if (configJsonCopy.dataSource && configJsonCopy.dataSource.argsJsonValue) {
          configJsonCopy.dataSource.argsJsonValue = configJsonCopy.dataSource.argsJsonValue.map(item => 
            typeof item === 'string' ? item : JSON.stringify(item)
          );
        }
        
        if (configJsonCopy.protocolDataConverter && configJsonCopy.protocolDataConverter.argsJsonValue) {
          configJsonCopy.protocolDataConverter.argsJsonValue = configJsonCopy.protocolDataConverter.argsJsonValue.map(item => 
            typeof item === 'string' ? item : JSON.stringify(item)
          );
        }
        
        if (configJsonCopy.dataCheckers && configJsonCopy.dataCheckers.length > 0) {
          configJsonCopy.dataCheckers.forEach(checker => {
            if (checker.argsJsonValue) {
              checker.argsJsonValue = checker.argsJsonValue.map(item => 
                typeof item === 'string' ? item : JSON.stringify(item)
              );
            }
          });
        }
        
        if (configJsonCopy.dataSink && configJsonCopy.dataSink.argsJsonValue) {
          configJsonCopy.dataSink.argsJsonValue = configJsonCopy.dataSink.argsJsonValue.map(item => 
            typeof item === 'string' ? item : JSON.stringify(item)
          );
        }
        
        if (configJsonCopy.dataConverter && configJsonCopy.dataConverter.argsJsonValue) {
          configJsonCopy.dataConverter.argsJsonValue = configJsonCopy.dataConverter.argsJsonValue.map(item => 
            typeof item === 'string' ? item : JSON.stringify(item)
          );
        }
        
        // 移除可能存在的非标准字段
        if (configJsonCopy.selectedDataSourceConfigJsonTreeData) {
          delete configJsonCopy.selectedDataSourceConfigJsonTreeData;
        }
        
        if (configJsonCopy.selectedDataSourceTclassInfoTreeData) {
          delete configJsonCopy.selectedDataSourceTclassInfoTreeData;
        }
        
        const submitData = {
          ...this.form,
          configJson: JSON.stringify(configJsonCopy),
          settingJsonConfig: JSON.stringify(settingJsonConfigCopy)
        };
        
        this.postRequest("mydataharbor/task/submit", submitData).then(res => {
          if (res.code == 0) {
            this.$message.success({
              message: "任务提交成功！",
              duration: 2000
            });
            this.initData();
            this.clearData();
          } else {
            this.$message.error(res.msg);
          }
          this.tableLoading = false;
        }).catch(() => {
          this.tableLoading = false;
          this.$message.error("任务提交失败，请检查网络连接");
        });
      }).catch(() => {
        // 用户取消提交
      });
    },
    
    // 验证任务表单
    validateTaskForm() {
      if (!this.form.taskName) {
        this.$message.warning("请输入任务名称");
        return false;
      }
      
      if (!this.form.pluginId) {
        this.$message.warning("请选择插件ID");
        return false;
      }
      
      if (!this.form.mydataharborCreatorClazz) {
        this.$message.warning("请选择创建器");
        return false;
      }
      
      if (!this.form.totalNumberOfPipeline || this.form.totalNumberOfPipeline <= 0) {
        this.$message.warning("管道数必须大于0");
        return false;
      }
      
      return true;
    },
    cancel() {
      this.dialogFormVisible = false;
      this.taskDetailVisible = false;
      this.dialogUpdateVisible = false;
      this.dialogStateVisible = false;
      this.dialogRecreateUpdateVisible = false;
      this.formStepActive = 0;
      this.clearData();
    },
    // 选择插件
    selectPluginId(value) {
      this.clazzList = [];
      if (this.type == "add") {
        this.form.mydataharborCreatorClazz = "";
      } else {
        this.recreateUpdateForm.mydataharborCreatorClazz = "";
      }
      this.pluginInstallList.forEach(plugin => {
        if (plugin.pluginId == value) {
          if (plugin.dataPipelineCreatorInfos != null) {
            plugin.dataPipelineCreatorInfos.forEach(dataSink => {
              if (dataSink.canCreatePipeline) {
                this.clazzList.push({
                  clazz: dataSink.clazz,
                  type: dataSink.type
                });
              }
            });
          }
        }
      });
    },
    // 选择创建器
    creatorClazzChange(val) {
      this.form.settingJsonConfig = {};
      this.form.configJson = {};
      if (val != "") {
        this.pluginInstallList.forEach(pluginInfo => {
          if (pluginInfo.pluginId == this.form.pluginId) {
            pluginInfo.dataPipelineCreatorInfos.forEach(creatorInfo => {
              if (creatorInfo.clazz == val) {
                creatorInfo.settingClassInfo.fieldName = "root";
                creatorInfo.configClassInfo.fieldName = "root";
                this.settingConfigJsonTreeData = [creatorInfo.settingClassInfo];
                this.taskConfigJsonTreeData = [creatorInfo.configClassInfo];
                for (const fieldInfo of creatorInfo.settingClassInfo
                  .fieldInfos) {
                  this.fillField(this.form.settingJsonConfig, fieldInfo);
                }
                for (const fieldInfo of creatorInfo.configClassInfo
                  .fieldInfos) {
                  this.fillField(this.form.configJson, fieldInfo);
                }
              }
            });
          }
        });
      }
    },
    // 任务详情
    taskDetail(task) {
      this.taskDetailForm = [];
      this.taskAssignedInfo = [];

      const row = JSON.parse(JSON.stringify(task));
      this.detailConfigJson = JSON.parse(task.configJson);
      this.detailTags = task.tags;
      this.detailSettingJsonConfig = JSON.parse(task.settingJsonConfig);
      // 任务分配信息
      const assignedInfo = task.taskAssignedInfo.assignedInfoMap;
      for (const rowKey in assignedInfo) {
        this.taskAssignedInfo.push(assignedInfo[rowKey]);
      }

      this.getRequest("mydataharbor/task/getTaskMonitorInfo", {
        taskId: task.taskId
      }).then(res => {
        if (res.code == 0) {
          this.taskMonitorInfos = [res.data];
        } else {
          this.$message.error(res.msg);
        }
      });

      // console.log(this.taskAssignedInfo);
      this.taskDetailForm.push(row);
      // console.log(this.taskDetailForm);
      this.taskDetailVisible = true;
    },
    // 任务修改弹框
    taskUpdate(task) {
      this.updateForm.taskId = task.taskId;
      this.updateForm.taskName = task.taskName;
      this.updateForm.totalNumberOfPipeline = task.totalNumberOfPipeline;
      this.updateForm.enableRebalance = task.enableRebalance;
      this.updateForm.enableLoadBalance = task.enableLoadBalance;
      this.updateForm.tags = task.tags;
      this.dialogUpdateVisible = true;
    },
    // 任务修改
    updateFormSubmit() {
      this.postRequest("mydataharbor/task/editTask", this.updateForm).then(
        res => {
          if (res.code == 0) {
            this.$message.info("任务修改成功！");
            this.initData();
          } else {
            this.$message.error(res.msg);
          }
        }
      );
      this.dialogUpdateVisible = false;
    },
    // 任务重建修改弹框
    taskRecreateUpdate(task) {
      this.recreateUpdateForm.taskId = task.taskId;
      this.recreateUpdateForm.configJson = JSON.parse(task.configJson);
      this.recreateUpdateForm.tags = task.tags;
      this.recreateUpdateForm.settingJsonConfig = JSON.parse(
        task.settingJsonConfig
      );

      this.recreateUpdateForm.groupName = task.groupName;
      this.recreateUpdateForm.pluginId = task.pluginId;
      this.recreateUpdateForm.mydataharborCreatorClazz =
        task.mydataharborCreatorClazz;
      this.recreateUpdateForm.taskName = task.taskName;
      this.recreateUpdateForm.totalNumberOfPipeline =
        task.totalNumberOfPipeline;
      this.recreateUpdateForm.enableRebalance = task.enableRebalance;
      this.recreateUpdateForm.enableLoadBalance = task.enableLoadBalance;

      // 先选择插件ID，这会清空创建器列表
      this.selectPluginId(task.pluginId);

      // 初始化所有组件
      this.initAllComponent();

      // 确保创建器被正确选中
      if (task.mydataharborCreatorClazz != "") {
        // 手动设置创建器值，确保它被选中
        this.recreateUpdateForm.mydataharborCreatorClazz = task.mydataharborCreatorClazz;

        // 保存原始配置
        const originalConfigJson = JSON.parse(JSON.stringify(this.recreateUpdateForm.configJson));
        const originalSettingJsonConfig = JSON.parse(JSON.stringify(this.recreateUpdateForm.settingJsonConfig));

        this.pluginInstallList.forEach(pluginInfo => {
          if (pluginInfo.pluginId == this.recreateUpdateForm.pluginId) {
            pluginInfo.dataPipelineCreatorInfos.forEach(creatorInfo => {
              if (creatorInfo.clazz == task.mydataharborCreatorClazz) {
                creatorInfo.settingClassInfo.fieldName = "root";
                creatorInfo.configClassInfo.fieldName = "root";
                this.settingConfigJsonTreeData = [creatorInfo.settingClassInfo];
                this.taskConfigJsonTreeData = [creatorInfo.configClassInfo];

                // 先填充默认值
                for (const fieldInfo of creatorInfo.settingClassInfo.fieldInfos) {
                  this.fillField(
                    this.recreateUpdateForm.settingJsonConfig,
                    fieldInfo
                  );
                }

                for (const fieldInfo of creatorInfo.configClassInfo.fieldInfos) {
                  this.fillField(this.recreateUpdateForm.configJson, fieldInfo);
                }

                // 然后恢复原始值，确保原始配置被保留
                this.recreateUpdateForm.configJson = this.mergeConfigs(
                  this.recreateUpdateForm.configJson,
                  originalConfigJson
                );

                this.recreateUpdateForm.settingJsonConfig = this.mergeConfigs(
                  this.recreateUpdateForm.settingJsonConfig,
                  originalSettingJsonConfig
                );
              }
            });
          }
        });
      }

      this.type = "addAndDelJob";
      this.dialogRecreateUpdateVisible = true;

      // 处理配置数据
      const configJson = this.recreateUpdateForm.configJson;

      // 处理数据源配置
      if (configJson.dataSource) {
        // 查找并设置数据源名称
        for (const dataSource of this.installDataSourceList) {
          if (dataSource.clazz === configJson.dataSource.clazz &&
              dataSource.pluginId === configJson.dataSource.pluginId) {
            this.selectedDataSourceName = dataSource.name;
            this.selectedDataSource = dataSource;
            break;
          }
        }

        // 处理参数JSON
        if (configJson.dataSource.argsJsonValue && configJson.dataSource.argsJsonValue.length > 0) {
          try {
            this.selectedDataSourceConfigJson = configJson.dataSource.argsJsonValue.map(item =>
              typeof item === 'string' ? JSON.parse(item) : item
            );
          } catch (e) {
            console.error("解析数据源参数失败:", e);
            this.selectedDataSourceConfigJson = [];
          }
        }
      }

      // 处理协议转换器配置
      if (configJson.protocolDataConverter) {
        // 查找并设置协议转换器名称
        for (const converter of this.installProtocolDataConverterList) {
          if (converter.clazz === configJson.protocolDataConverter.clazz &&
              converter.pluginId === configJson.protocolDataConverter.pluginId) {
            this.selectedProtocolDataConverterName = converter.name;
            this.selectedProtocolDataConverter = converter;
            break;
          }
        }

        // 处理参数JSON
        if (configJson.protocolDataConverter.argsJsonValue && configJson.protocolDataConverter.argsJsonValue.length > 0) {
          try {
            this.selectedProtocolDataConverterConfigJson = configJson.protocolDataConverter.argsJsonValue.map(item =>
              typeof item === 'string' ? JSON.parse(item) : item
            );
          } catch (e) {
            console.error("解析协议转换器参数失败:", e);
            this.selectedProtocolDataConverterConfigJson = [];
          }
        }
      }

      // 处理数据检查器配置
      if (configJson.dataCheckers && configJson.dataCheckers.length > 0) {
        this.selectedCheckerNames = [];
        this.selectedCheckers = [];
        this.selectedCheckerConfigJsons = [];

        configJson.dataCheckers.forEach((checker, index) => {
          // 查找对应的检查器
          for (const installedChecker of this.installCheckers) {
            if (installedChecker.clazz === checker.clazz &&
                installedChecker.pluginId === checker.pluginId) {
              this.selectedCheckerNames.push(installedChecker.name);
              this.selectedCheckers.push(installedChecker);

              // 处理参数JSON
              if (checker.argsJsonValue && checker.argsJsonValue.length > 0) {
                try {
                  const configJson = checker.argsJsonValue.map(item =>
                    typeof item === 'string' ? JSON.parse(item) : item
                  );
                  this.selectedCheckerConfigJsons.push(configJson);
                } catch (e) {
                  console.error("解析检查器参数失败:", e);
                  this.selectedCheckerConfigJsons.push([]);
                }
              } else {
                this.selectedCheckerConfigJsons.push([]);
              }

              break;
            }
          }
        });
      }

      // 处理数据输出源配置
      if (configJson.dataSink) {
        // 查找并设置数据输出源名称
        for (const sink of this.installDataSinkList) {
          if (sink.clazz === configJson.dataSink.clazz &&
              sink.pluginId === configJson.dataSink.pluginId) {
            this.selectedDataSinkName = sink.name;
            this.selectedDataSink = sink;
            break;
          }
        }

        // 处理参数JSON
        if (configJson.dataSink.argsJsonValue && configJson.dataSink.argsJsonValue.length > 0) {
          try {
            this.selectedDataSinkConfigJson = configJson.dataSink.argsJsonValue.map(item =>
              typeof item === 'string' ? JSON.parse(item) : item
            );
          } catch (e) {
            console.error("解析数据输出源参数失败:", e);
            this.selectedDataSinkConfigJson = [];
          }
        }
      }

      // 处理数据转换器配置
      if (configJson.dataConverter) {
        // 查找并设置数据转换器名称
        for (const converter of this.installDataConverters) {
          if (converter.clazz === configJson.dataConverter.clazz &&
              converter.pluginId === configJson.dataConverter.pluginId) {
            this.selectedDataConverterName = converter.name;
            this.selectedDataConverter = converter;
            break;
          }
        }

        // 处理参数JSON
        if (configJson.dataConverter.argsJsonValue && configJson.dataConverter.argsJsonValue.length > 0) {
          try {
            this.selectedDataConverterConfigJson = configJson.dataConverter.argsJsonValue.map(item =>
              typeof item === 'string' ? JSON.parse(item) : item
            );
          } catch (e) {
            console.error("解析数据转换器参数失败:", e);
            this.selectedDataConverterConfigJson = [];
          }
        }
      }
    },
    //重建任务修改
    recreateUpdateFormSubmit() {
      // 深拷贝配置对象，避免修改原始对象
      const configJsonCopy = JSON.parse(JSON.stringify(this.recreateUpdateForm.configJson));
      const settingJsonConfigCopy = JSON.parse(JSON.stringify(this.recreateUpdateForm.settingJsonConfig));

      // 确保数据格式正确
      if (configJsonCopy.dataSource && configJsonCopy.dataSource.argsJsonValue) {
        configJsonCopy.dataSource.argsJsonValue = configJsonCopy.dataSource.argsJsonValue.map(item =>
          typeof item === 'string' ? item : JSON.stringify(item)
        );
      }

      if (configJsonCopy.protocolDataConverter && configJsonCopy.protocolDataConverter.argsJsonValue) {
        configJsonCopy.protocolDataConverter.argsJsonValue = configJsonCopy.protocolDataConverter.argsJsonValue.map(item =>
          typeof item === 'string' ? item : JSON.stringify(item)
        );
      }

      if (configJsonCopy.dataCheckers && configJsonCopy.dataCheckers.length > 0) {
        configJsonCopy.dataCheckers.forEach(checker => {
          if (checker.argsJsonValue) {
            checker.argsJsonValue = checker.argsJsonValue.map(item =>
              typeof item === 'string' ? item : JSON.stringify(item)
            );
          }
        });
      }

      if (configJsonCopy.dataSink && configJsonCopy.dataSink.argsJsonValue) {
        configJsonCopy.dataSink.argsJsonValue = configJsonCopy.dataSink.argsJsonValue.map(item =>
          typeof item === 'string' ? item : JSON.stringify(item)
        );
      }

      if (configJsonCopy.dataConverter && configJsonCopy.dataConverter.argsJsonValue) {
        configJsonCopy.dataConverter.argsJsonValue = configJsonCopy.dataConverter.argsJsonValue.map(item =>
          typeof item === 'string' ? item : JSON.stringify(item)
        );
      }

      // 移除可能存在的非标准字段
      if (configJsonCopy.selectedDataSourceConfigJsonTreeData) {
        delete configJsonCopy.selectedDataSourceConfigJsonTreeData;
      }

      if (configJsonCopy.selectedDataSourceTclassInfoTreeData) {
        delete configJsonCopy.selectedDataSourceTclassInfoTreeData;
      }

      const submitData = {
        ...this.recreateUpdateForm,
        configJson: JSON.stringify(configJsonCopy),
        settingJsonConfig: JSON.stringify(settingJsonConfigCopy)
      };

      this.postRequest(
        "mydataharbor/task/recreateTask",
        submitData
      ).then(res => {
        if (res.code == 0) {
          this.$message.info("任务重建成功！");
          this.initData();
        } else {
          this.$message.error(res.msg);
        }
      });
      this.dialogRecreateUpdateVisible = false;
    },
    // 复制任务
    taskFork(task) {
      this.dialogName = "复制任务";
      this.form = JSON.parse(JSON.stringify(task));
      this.form.configJson = JSON.parse(task.configJson);
      this.form.settingJsonConfig = JSON.parse(task.settingJsonConfig);
      
      // 生成新的任务ID，避免冲突
      this.form.taskId = "";
      
      this.dialogFormVisible = true;
      this.formStepActive = 0;
      // 先选择插件ID，这会清空创建器列表
      this.selectPluginId(task.pluginId);

      // 初始化所有组件
      this.initAllComponent();

      // 确保创建器被正确选中
      if (task.mydataharborCreatorClazz != "") {
        // 手动设置创建器值，确保它被选中
        this.form.mydataharborCreatorClazz = task.mydataharborCreatorClazz;

        // 保存原始配置
        const originalConfigJson = JSON.parse(JSON.stringify(this.form.configJson));
        const originalSettingJsonConfig = JSON.parse(JSON.stringify(this.form.settingJsonConfig));

        this.pluginInstallList.forEach(pluginInfo => {
          if (pluginInfo.pluginId == this.form.pluginId) {
            pluginInfo.dataPipelineCreatorInfos.forEach(creatorInfo => {
              if (creatorInfo.clazz == task.mydataharborCreatorClazz) {
                creatorInfo.settingClassInfo.fieldName = "root";
                creatorInfo.configClassInfo.fieldName = "root";
                this.settingConfigJsonTreeData = [creatorInfo.settingClassInfo];
                this.taskConfigJsonTreeData = [creatorInfo.configClassInfo];

                // 先填充默认值
                for (const fieldInfo of creatorInfo.settingClassInfo.fieldInfos) {
                  this.fillField(this.form.settingJsonConfig, fieldInfo);
                }

                for (const fieldInfo of creatorInfo.configClassInfo.fieldInfos) {
                  this.fillField(this.form.configJson, fieldInfo);
                }

                // 然后恢复原始值，确保原始配置被保留
                this.form.configJson = this.mergeConfigs(
                  this.form.configJson,
                  originalConfigJson
                );

                this.form.settingJsonConfig = this.mergeConfigs(
                  this.form.settingJsonConfig,
                  originalSettingJsonConfig
                );
              }
            });
          }
        });
      }

      // 处理配置数据
      const configJson = this.form.configJson;

      // 处理数据源配置
      if (configJson.dataSource) {
        // 查找并设置数据源名称
        for (const dataSource of this.installDataSourceList) {
          if (dataSource.clazz === configJson.dataSource.clazz &&
              dataSource.pluginId === configJson.dataSource.pluginId) {
            this.selectedDataSourceName = dataSource.name;
            this.selectedDataSource = dataSource;
            break;
          }
        }

        // 处理参数JSON
        if (configJson.dataSource.argsJsonValue && configJson.dataSource.argsJsonValue.length > 0) {
          try {
            this.selectedDataSourceConfigJson = configJson.dataSource.argsJsonValue.map(item =>
              typeof item === 'string' ? JSON.parse(item) : item
            );
          } catch (e) {
            console.error("解析数据源参数失败:", e);
            this.selectedDataSourceConfigJson = [];
          }
        }
      }

      // 处理协议转换器配置
      if (configJson.protocolDataConverter) {
        // 查找并设置协议转换器名称
        for (const converter of this.installProtocolDataConverterList) {
          if (converter.clazz === configJson.protocolDataConverter.clazz &&
              converter.pluginId === configJson.protocolDataConverter.pluginId) {
            this.selectedProtocolDataConverterName = converter.name;
            this.selectedProtocolDataConverter = converter;
            break;
          }
        }

        // 处理参数JSON
        if (configJson.protocolDataConverter.argsJsonValue && configJson.protocolDataConverter.argsJsonValue.length > 0) {
          try {
            this.selectedProtocolDataConverterConfigJson = configJson.protocolDataConverter.argsJsonValue.map(item =>
              typeof item === 'string' ? JSON.parse(item) : item
            );
          } catch (e) {
            console.error("解析协议转换器参数失败:", e);
            this.selectedProtocolDataConverterConfigJson = [];
          }
        }
      }

      // 处理数据检查器配置
      if (configJson.dataCheckers && configJson.dataCheckers.length > 0) {
        this.selectedCheckerNames = [];
        this.selectedCheckers = [];
        this.selectedCheckerConfigJsons = [];

        configJson.dataCheckers.forEach((checker, index) => {
          // 查找对应的检查器
          for (const installedChecker of this.installCheckers) {
            if (installedChecker.clazz === checker.clazz &&
                installedChecker.pluginId === checker.pluginId) {
              this.selectedCheckerNames.push(installedChecker.name);
              this.selectedCheckers.push(installedChecker);

              // 处理参数JSON
              if (checker.argsJsonValue && checker.argsJsonValue.length > 0) {
                try {
                  const configJson = checker.argsJsonValue.map(item =>
                    typeof item === 'string' ? JSON.parse(item) : item
                  );
                  this.selectedCheckerConfigJsons.push(configJson);
                } catch (e) {
                  console.error("解析检查器参数失败:", e);
                  this.selectedCheckerConfigJsons.push([]);
                }
              } else {
                this.selectedCheckerConfigJsons.push([]);
              }

              break;
            }
          }
        });
      }

      // 处理数据输出源配置
      if (configJson.dataSink) {
        // 查找并设置数据输出源名称
        for (const sink of this.installDataSinkList) {
          if (sink.clazz === configJson.dataSink.clazz &&
              sink.pluginId === configJson.dataSink.pluginId) {
            this.selectedDataSinkName = sink.name;
            this.selectedDataSink = sink;
            break;
          }
        }

        // 处理参数JSON
        if (configJson.dataSink.argsJsonValue && configJson.dataSink.argsJsonValue.length > 0) {
          try {
            this.selectedDataSinkConfigJson = configJson.dataSink.argsJsonValue.map(item =>
              typeof item === 'string' ? JSON.parse(item) : item
            );
          } catch (e) {
            console.error("解析数据输出源参数失败:", e);
            this.selectedDataSinkConfigJson = [];
          }
        }
      }

      // 处理数据转换器配置
      if (configJson.dataConverter) {
        // 查找并设置数据转换器名称
        for (const converter of this.installDataConverters) {
          if (converter.clazz === configJson.dataConverter.clazz &&
              converter.pluginId === configJson.dataConverter.pluginId) {
            this.selectedDataConverterName = converter.name;
            this.selectedDataConverter = converter;
            break;
          }
        }

        // 处理参数JSON
        if (configJson.dataConverter.argsJsonValue && configJson.dataConverter.argsJsonValue.length > 0) {
          try {
            this.selectedDataConverterConfigJson = configJson.dataConverter.argsJsonValue.map(item =>
              typeof item === 'string' ? JSON.parse(item) : item
            );
          } catch (e) {
            console.error("解析数据转换器参数失败:", e);
            this.selectedDataConverterConfigJson = [];
          }
        }
      }

      this.type = "add";
    },
    // 任务状态弹框
    taskStates(task) {
      this.stateForm.taskId = task.taskId;
      this.stateForm.taskState = task.taskState;
      this.dialogStateVisible = true;
    },
    // 删除任务
    taskDelete(task) {
      this.$confirm("是否永久删除该任务：" + task.taskId, "确认信息", {
        distinguishCancelAndClose: true,
        confirmButtonText: "删除",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        this.postRequest(
          "/mydataharbor/task/deleteTask?taskId=" + task.taskId
        ).then(res => {
          if (res.code == 0) {
            this.$message({
              type: "info",
              message: "删除成功！"
            });
          } else {
            this.$message({
              type: "warning",
              message: "删除失败！" + res.msg
            });
          }
        });
        this.initData();
      });
    },
    updateStateFormSubmit() {
      this.postRequest(
        "mydataharbor/task/manageTaskState?taskId=" +
          this.stateForm.taskId +
          "&taskState=" +
          this.stateForm.taskState
      ).then(res => {
        if (res.code == 0) {
          this.$message.info("任务状态修改成功！");
          this.initData();
        } else {
          this.$message.error(res.msg);
        }
      });
      this.dialogStateVisible = false;
    },
    // 分页处理
    initPageData() {
      const dataSource = this.filteredTaskList || this.taskList;
      this.pageTotal = dataSource.length;
      this.totalPage = {};
      
      for (let i = 0; i < Math.ceil(this.pageTotal / this.pageSize); i++) {
        // 每一页都是一个数组 形如 [['第一页的数据'],['第二页的数据'],['第三页数据']]
        // 根据每页显示数量 将后台的数据分割到 每一页,假设pageSize为5， 则第一页是1-5条，即slice(0,5)，第二页是6-10条，即slice(5,10)...
        this.totalPage[i + 1] = dataSource.slice(
          this.pageSize * i,
          this.pageSize * (i + 1)
        );
      }
      this.handlePageChange(1);
    },
    handlePageChange(pageNo) {
      this.currentPage = pageNo;
      // 获取到数据后显示第一页内容
      this.dataShow = this.totalPage[this.currentPage];
    },
    handleSizeChange(size) {
      this.pageSize = size;
      this.initPageData();
    },
    // 多选
    handleSelectionChange(val) {
      this.multipleSelection = val;
    },
    // 删除多条数据
    batchDelete() {
      console.log(this.multipleSelection);
      if (this.multipleSelection.length == 0) {
        this.$message.info("当前未选择任务任务数据，请先勾选需要删除的数据！");
        return;
      }
      let deleteCount = 0;
      this.$confirm(
        "是否永久删除已选的" + this.multipleSelection.length + "条数据",
        "确认信息",
        {
          distinguishCancelAndClose: true,
          confirmButtonText: "删除",
          cancelButtonText: "取消",
          type: "warning"
        }
      ).then(() => {
        this.multipleSelection.forEach(task => {
          // console.log(task.taskId)
          this.postRequest(
            "/mydataharbor/task/deleteTask?taskId=" + task.taskId
          ).then(res => {
            if (res.code == 0) {
              deleteCount = deleteCount + 1;
              if (deleteCount == this.multipleSelection.length) {
                this.$message({
                  type: "info",
                  message: "成功删除" + deleteCount + "条数据！"
                });
              }
            } else {
              this.$message.error(res.msg);
            }
          });
        });
        this.reload();
      });
    },
    renderTreeContent(h, { node, data, store }) {
      return (
        <span class="custom-tree-node">
          <span>
            {data.fieldName} {data.title} 【类型:{data.clazzStr}】【
            {data["array"] == true
              ? "数组"
              : data["map"] == true
              ? "map"
              : data["baseType"] == true
              ? "基础类型"
              : "对象"}
            】
            {data["enumeration"] == true
              ? "【枚举】候选值:" + JSON.stringify(data["candidateValue"])
              : ""}
            {data["require"] == true ? "【必须】" : "【非必须】"}
            {data["defaultValue"] != null && data["defaultValue"] != ""
              ? "【默认值：" + data["defaultValue"] + "】"
              : ""}
            {data["des"]}
          </span>
        </span>
      );
    },
    fillField(json, fieldInfo) {
      if (fieldInfo.require) {
        if (fieldInfo.array) {
          json[fieldInfo.fieldName] = [];
        } else if (fieldInfo.map) {
          json[fieldInfo.fieldName] = {};
        } else if (fieldInfo.baseType) {
          json[fieldInfo.fieldName] = fieldInfo.defaultValue;
        } else {
          json[fieldInfo.fieldName] = {};
        }
        if (fieldInfo.fieldInfos != null && fieldInfo.fieldInfos.length > 0) {
          for (const subFieldInfo of fieldInfo.fieldInfos) {
            this.fillField(json[fieldInfo.fieldName], subFieldInfo);
          }
        }
      }
    },

    buildArgsTypeInfo(argsTypeInfo) {
      var configJson = [];
      for (var argsTypeInfoItem of argsTypeInfo) {
        var obj = {};
        if (argsTypeInfoItem.array) {
          obj = [];
        } else if (argsTypeInfoItem.map) {
          obj = {};
        } else if (argsTypeInfoItem.baseType) {
          obj =
            argsTypeInfoItem.defaultValue == null
              ? ""
              : argsTypeInfoItem.defaultValue;
        }
        if (
          argsTypeInfoItem.fieldInfos != null &&
          argsTypeInfoItem.fieldInfos.length > 0
        ) {
          for (const subFieldInfo of argsTypeInfoItem.fieldInfos) {
            this.fillField(obj, subFieldInfo);
          }
        }
        configJson.push(obj);
      }
      return configJson;
    },
    //可视化界面下一步
    viewFormNext() {
      if (this.viewFormActiveIndex == 1) {
        if (this.selectedDataSourceName == "") {
          this.$message({
            message: "请选择输入源",
            type: "warning",
            duration: 2000,
            showClose: true
          });
          return;
        }
        if (this.selectedProtocolDataConverterName == "") {
          this.$message({
            message: "请选择协议转换器",
            type: "warning",
            duration: 2000,
            showClose: true
          });
          return;
        }
      } else if (this.viewFormActiveIndex == 2) {
        console.log(this.selectedCheckerNames);
        for (var name of this.selectedCheckerNames) {
          if (name == "") {
            this.$message({
              message: "请配置过滤器，如不需要请删除",
              type: "warning",
              duration: 2000,
              showClose: true
            });
            return;
          }
        }
      } else if (this.viewFormActiveIndex == 3) {
        if (this.selectedDataSinkName == "") {
          this.$message({
            message: "请选择输出源",
            type: "warning",
            duration: 2000,
            showClose: true
          });
          return;
        }
      }
      this.viewFormActiveIndex++;
    },
    //可视化界面上一步
    viewFormPre() {
      this.viewFormActiveIndex--;
    },
    //可视化配置生成json
    viewFormConfirm() {
      if (this.selectedDataConverterName == "") {
        this.$message({
          message: "请选择数据转换器",
          type: "warning",
          duration: 2000,
          showClose: true
        });
        return;
      }
      //从选中的组件中生成json
      console.log(this.selectedDataSource);
      var newConfigJson = "";
      if (this.type == "add") {
        newConfigJson = JSON.parse(JSON.stringify(this.form.configJson));
      } else if (this.type == "addAndDelJob") {
        newConfigJson = JSON.parse(
          JSON.stringify(this.recreateUpdateForm.configJson)
        );
      } else {
        newConfigJson = JSON.parse(JSON.stringify(this.updateForm.configJson));
      }
      newConfigJson.dataSource.pluginId = this.selectedDataSource.pluginId;
      newConfigJson.dataSource.clazz = this.selectedDataSource.clazz;
      newConfigJson.dataSource.argsType =
        this.selectedDataSource.argsType == null
          ? []
          : this.selectedDataSource.argsType;
      newConfigJson.dataSource.argsJsonValue = [];
      console.log(JSON.stringify(this.selectedDataSourceConfigJson))
      for (var obj of this.selectedDataSourceConfigJson) {
        newConfigJson.dataSource.argsJsonValue.push(JSON.stringify(obj));
      }

      newConfigJson.protocolDataConverter.pluginId = this.selectedProtocolDataConverter.pluginId;
      newConfigJson.protocolDataConverter.clazz = this.selectedProtocolDataConverter.clazz;
      newConfigJson.protocolDataConverter.argsType =
        this.selectedProtocolDataConverter.argsType == null
          ? []
          : this.selectedProtocolDataConverter.argsType;
      newConfigJson.protocolDataConverter.argsJsonValue = [];
      for (var obj of this.selectedProtocolDataConverterConfigJson) {
        newConfigJson.protocolDataConverter.argsJsonValue.push(
          JSON.stringify(obj)
        );
      }

      for (var i = 0; i < this.selectedCheckers.length; i++) {
        var selectedChecker = this.selectedCheckers[i];
        var checkerArgsJsonValue = [];
        for (var obj of this.selectedCheckerConfigJsons[i]) {
          checkerArgsJsonValue.push(JSON.stringify(obj));
        }
        newConfigJson.dataCheckers.push({
          pluginId: selectedChecker.pluginId,
          clazz: selectedChecker.clazz,
          argsType:
            selectedChecker.argsType == null ? [] : selectedChecker.argsType,
          argsJsonValue: checkerArgsJsonValue
        });
      }

      newConfigJson.dataConverter.pluginId = this.selectedDataConverter.pluginId;
      newConfigJson.dataConverter.clazz = this.selectedDataConverter.clazz;
      newConfigJson.dataConverter.argsType =
        this.selectedDataConverter.argsType == null
          ? []
          : this.selectedDataConverter.argsType;
      newConfigJson.dataConverter.argsJsonValue = [];
      for (var obj of this.selectedDataConverterConfigJson) {
        newConfigJson.dataConverter.argsJsonValue.push(JSON.stringify(obj));
      }

      newConfigJson.dataSink.pluginId = this.selectedDataSink.pluginId;
      newConfigJson.dataSink.clazz = this.selectedDataSink.clazz;
      newConfigJson.dataSink.argsType =
        this.selectedDataSink.argsType == null
          ? []
          : this.selectedDataSink.argsType;
      newConfigJson.dataSink.argsJsonValue = [];
      for (var obj of this.selectedDataSinkConfigJson) {
        newConfigJson.dataSink.argsJsonValue.push(JSON.stringify(obj));
      }

      if (this.type == "add") {
        this.form.configJson = newConfigJson;
      } else if (this.type == "addAndDelJob") {
        this.recreateUpdateForm.configJson = newConfigJson;
      } else {
        this.updateForm.configJson = newConfigJson;
      }
      this.taskConfigDefaultActiveModel = "json";
    },
    // 处理下拉菜单命令
    handleCommand(command, row) {
      switch (command) {
        case 'update':
          this.taskUpdate(row);
          break;
        case 'recreate':
          this.taskRecreateUpdate(row);
          break;
        case 'fork':
          this.taskFork(row);
          break;
        case 'state':
          this.taskStates(row);
          break;
        case 'start':
          this.quickChangeState(row, 'started');
          break;
        case 'suspend':
          this.quickChangeState(row, 'suspend');
          break;
        case 'delete':
          this.taskDelete(row);
          break;
      }
    },
    
    // 快速修改任务状态
    quickChangeState(task, state) {
      this.$confirm(`确定要将任务 "${task.taskName || task.taskId}" 的状态修改为${this.states[state]}吗？`, "确认信息", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        this.tableLoading = true;
        this.postRequest(
          `mydataharbor/task/manageTaskState?taskId=${task.taskId}&taskState=${state}`
        ).then(res => {
          if (res.code == 0) {
            this.$message.success(`任务状态修改成功！`);
            this.initData();
          } else {
            this.$message.error(res.msg);
          }
          this.tableLoading = false;
        }).catch(() => {
          this.tableLoading = false;
          this.$message.error("状态修改失败，请检查网络连接");
        });
      });
    },
    
    recreateClose() {
      this.type = "";
    },
    
    // 合并配置，保留原始值
    mergeConfigs(defaultConfig, originalConfig) {
      if (!originalConfig || typeof originalConfig !== 'object') {
        return defaultConfig;
      }

      if (!defaultConfig || typeof defaultConfig !== 'object') {
        return originalConfig;
      }

      const result = { ...defaultConfig };

      for (const key in originalConfig) {
        if (originalConfig.hasOwnProperty(key)) {
          if (
            originalConfig[key] !== null &&
            typeof originalConfig[key] === 'object' &&
            !Array.isArray(originalConfig[key]) &&
            result.hasOwnProperty(key) &&
            result[key] !== null &&
            typeof result[key] === 'object' &&
            !Array.isArray(result[key])
          ) {
            // 递归合并嵌套对象
            result[key] = this.mergeConfigs(result[key], originalConfig[key]);
          } else {
            // 使用原始值覆盖默认值
            result[key] = originalConfig[key];
          }
        }
      }

      return result;
    }
  }
};
</script>

<style scoped>
/deep/ .el-col-24 {
  width: 50%;
  margin-left: -6%;
}

/deep/ .el-alert--info.is-light {
  background-color: #ffffff;
}

.demo-table-expand {
  font-size: 0;
}

.demo-table-expand label {
  width: 90px;
  color: #99a9bf;
}

.demo-table-expand .el-form-item {
  margin-right: 0;
  margin-bottom: 0;
  width: 50%;
}
</style>
